-
Notifications
You must be signed in to change notification settings - Fork 295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Removing event listeners through an identifier #208
Comments
Couldn't addEventListener just return a handle object? That then you would call removeEventListener on in the future? |
@dtapuska it's been a while, but I think the concern with that is having to manage the objects, similar to how the current setup requires holding references to the callback. Having a group feature (suggestion from Twitter as a better name for class) makes this kind of management much simpler. A single widget/component could register dozens of event listeners, all using the widget's name. And then when the widget is removed it simply removes all the event listeners with it, without having to keep track of objects and such. |
I just think it's a little funny we (almost) have WebRTC, Asm.js, bg workers, sockets, etc... Yet DOM events slipped by, left to leak all over the place for years. |
please don't introduce more magic strings into the API. |
Allowing any value as the key (including a string) seems fine. You just later test with ===. Then people who want to use symbols or objects or whatever can do that, but most of us can just use strings like we're used to doing with jQuery. |
What's this now? Are we talking about the options object being added for passive event listeners? |
Yes, this. |
@jsen- could you explain how the string would be magic? It's developer-provided. |
@annevk you're right, there's nothing magic about them, I just don't like using strings as identifiers. |
Could
Using an id rather than holding onto references to the handler could also reduce the potential for memory leaks. What would be great is if the returned And to be clear, I also think @annevk's proposal is great, but why not both? |
@adamdbradley @dtapuska asked that above and @annevk replied that he thought the group feature was strictly superior to returning a single handle. Any feedback on the differences between those two approaches to the problem? I agree with Anne that using some group identifier (possibly an object, not just a string) is probably easier to manager than having to track an id. If you're going to track an ID anyway, you could just be tracking the callback in the same way. In fact, |
@RByers Being able to group many event listeners through one common identifier sounds great, and I see the value of it because you're not tracking anything at all.
So to remove a group, would it have to strictly be the same object that was used in the addEventListener, or is it any object but with the same string value for |
@adamdbradley the idea would be |
A suggestion from @adamdbradley that I did not explicitly address was making the identifier global. I would prefer not doing that as that means we need to globally keep track of these listeners, whereas currently they're always neatly scoped to an object. The only remaining question here in my mind is whether we should overload |
@annevk I like the idea of conforming to the the "add/delete" convention, however if we're overloading |
@mkay581 the main difference is that with |
@annevk Yeah, I vote for the latter. |
Sorry to disagree, I find it superfluous, and not great to put such a 'tag'/group key in listeners options if the removeEventListener repetitions annoy you, you could do for ex:
|
So is there an API proposal here? Do we know it is such which script libraries would use, or would they still just have some their own API on top of that? |
@rniwa thoughts? I am personally unconvinced at this point. Seems like something the JS libraries could easily implement so I am not sure its is worth complicating the engine. That said, I don't think this would be a lot of work to implement. |
Hi all. A bit surprised at some of these questions, @smaug----.
Yes. It's the one discussed at length in this thread, and concretized by PR #469. I noted you commented over there, so I'm a bit confused why you state here you're unable to find the API proposal.
Yes; jQuery is a prime candidate, since that is where this feature originates. As are all the frameworks built on top of it. In general this feature is highly desired by frameworks since they like to be able to manage their event listeners en-masse. Right now they are having to keep a side-table of function references so they can remove them later. This is especially the case for custom elements, which are like little self-contained frameworks themselves. See also #412; although this proposal doesn't subsume that one, it provides a less-dangerous subset that addresses many of the same use cases (e.g. allowing coordination via disparate parts of the code/different libraries as long as they agree on the same
Indeed. This is part of that effort, going back years; there's actually been a lot of thought about this, which you can see from the various discussions here and, back in the day, on www-dom. (It's not "random".) Removing event listeneres by group is a top candidate, as is event delegation (#215), based on patterns that a majority of popular libraries end up inventing independently. The
I certainly understand that everything has a cost. I'm a bit surprised you think I need to be reminded of that. Furthermore, as I explain a bit more below, I think this will overall increase the speed of web pages.
Yes, this is definitely not a new primitive. This is part of a different effort, to make the platform more ergonomic based on the feedback we've gotten over the years; we've provided the primitives, seen what people have built, and now it's time to bring that knowledge back into the platform. It's more along the lines of the existing The other point is that this particular proposal fits well in the effort/reward tradeoff, as you point out. Personally I think this and #467 are a slam dunk in that regard. #215 is less clear; it'll likely be more effort to implement, but also higher reward. We'll be able to evaluate the actual tradeoff there better once we have a spec, and possibly a prototype in Blink. |
PRs should be for actual changes for the spec once the proposal is ready. I wasn't going to do any review there. It makes tracking all the discussion hard if some discussion happens in issue and some in pr. PR should be just once the proposal is concrete and just minor editorial reviews are needed.
What about other script libraries than jQuery? React.js happens to be hip and cool currently, would it use this stuff? What about other libraries?
We all need to be reminded about that all the time. Or at least I need to remind myself. (Sorry if I'm a bit reluctant right now. I just happened to review implementation for .labels attribute recently and realized how bad API even such a small feature can be - if implemented correctly, it slows down pretty much all DOM mutations) |
Is capture part of the key? If so, the browser already has to normalize, to prevent these from being added twice: el.addEventListener("type", cb, true);
el.addEventListener("type", cb, { capture: true }); |
I think it is, yes. I just meant that we might not want to extend the key further to keep things reasonably straightforward. |
I've updated #469 to allow only strings and symbols, and to allow a sequence of groups (although I kept the name Next up is updating the tests. Still hoping for some implementer interest beyond Chrome; thoughts @rniwa or @smaug----? :) |
@annevk Hm.. On the other hand, both of these options are relatively new, and both are the only two options in existence right now that don't modify behaviour of the handler itself ( I wonder if in the previous specification of I would expect that to be a low risk change, in terms of web-compat. It's only now with grouping that we observe potential user confusion and use cases for one way or the other. Although I see now what @LeaVerou meant. If we take away support for 1-to-many association (multiple groups), this problem/question won't exist. Users would naturally hit the silent ignore of addEventListener when adding a second version, as they do now. el.addEventListener("type", cb, { once: true });
el.addEventListener("type", cb); // ignored |
I can't find a discussion right now though I do remember we had some. The main question is whether there's a use for reusing a callback on the same event target object outside capture/non-capture. I don't think there's a big use for that and therefore I'd prefer keeping the key simple. |
I like this proposal.
I think it is confusing that there is a difference between I think it would be nice if |
It appears to me that supporting multiple groups to be associated with seems like an unnecessary complexity. It also feels like something that belong in a framework / library. Why don't we just forego that aspect. If it turns out be useful, we can always add it later. |
If it's decided it's better to add it later, it'd be good if there was no stringification performed on the |
I'm not really comfortable departing from every other web API that accepts a string by throwing if your string comes via conversion from an iterable (or other value). @rniwa I thought it added too much complexity too, but after writing the spec I think it ended up being not so bad. Take a look at the PR (you can use the preview link to see a rendered version) and let me know whether you still believe it should be removed? |
I don't think it matters where the spec'ing it simple or that you can implement it easily. It's more of a matter of the API complexity. Although I can see the argument for supporting multiple values given we do support DOMTokenList for class names on an element. The use case here is very similar to that. |
If the complexity doesn't get in the way of simple usage, I'm not sure what's the problem exactly. Users don't have to learn about sequences in |
Keeping core DOM API simple is quite important. Every new complexity we add impose a more cognitive stress on someone trying to learn how to code in the Web. Are you sure having the sequence support would be useful in 10 years? How about in 20 years? Any new API surface we're adding today should be looked at in that kind of timespan, not just next 2-3 years. |
Again, if they don't need it, it doesn’t get in their way. They can just use strings and symbols until the end of time. Understanding someone else’s code could be an issue, but for a common pattern like this, it's better to standardize one natural way of doing it than to have a number of different helpers and patterns that novices have to process. It's so common in a method signature to accept either a singular item or an array/iterable for multiple that many users might even guess it (and be surprised if it doesn’t work). Anyhow, if we really want to find out whether that is useful and how much, we should probably ask the jQuery maintainers instead of just guessing based on our experience (or lack thereof). jQuery has allowed multiple namespaces for its events for years, so I suspect they may have some idea of usage stats. @addyosmani, any thoughts? (notice how the use case for multiple namespaces in their docs is the same I mentioned earlier in this thread: one for plugin name, one for purpose)
ZOMG really, that’s how standards work?!? I would never have guessed!!!11 What do I know about standards after all? 🙄 I don't see why if multiple groups are useful today they wouldn't be in 10 or 20 years. It's not a transitional feature of any sort. The same reasons are still going to exist. Do you have any reasons to think that is not the case? Given that you don't seem to understand why multiple groups are needed today, it seems odd that you would see those (nonexistent from your perspective) reasons going away in 10 or 20 years. @domenic Just wondering, would the group info be available on the event object? Should it? Maybe something to think about. |
How would you make it available on the event? It's tied to the event listener, no? |
Please remember to be kind and curteous in discussions. There's no need to be sarcastic or rude. https://whatwg.org/code-of-conduct |
@annevk Yeah, it's tied to the event listener and cannot (should not) be exposed to the event object. However, I do see @LeaVerou's perspective and had to think about this a few times. The event object is constructed, like any other object, at the time the event "happens". E.g. you can manually do |
From a jQuery-experience point of view this seems like a good feature for what I've seen to be the most common use of namespaces, which is removing a group of event listeners for a plugin. Although there's a lot of painful logic to deal with multiple namespaces, I doubt it's used that often. We don't have any way to collect stats on that so I could be wrong. The PR says that the However, note that jQuery does more with namespaces than just adding or removing listeners. It exposes I doubt jQuery could use this new event interface unless we deprecated and removed the existing namespace features, they are used in the wild. However, I don't think jQuery's ability to adopt the interface in its own codebase should be the litmus test for new features in the standard. It would be good to check with other frameworks and libraries to find out whether they could take advantage of this feature. They may have similar reasons why it doesn't quite match their needs.
I'm pretty sure most of the jQuery team was aware of this pattern. However, |
This thread is fairly long and has not been updated since July. Can someone summarize the status of this proposal, to facilitate any further steps? Per my understanding (although admittedly gave up on reading everything): As a side note (not sure if this was mentioned already), I think both the existing Thank you. |
There's a proposal in #469, but there's no real implementer interest to pursue this so this is mainly blocked on getting that. |
Having read through this thread again it seems there's some interest in this proposal from implementers, but one concern that was raised is that multiple groups might be too much for v1. Then @dmethvin brought up an interesting point which is that this does not give us feature parity with jQuery as they also expose the group on the event object during any listener callbacks. Additionally, Dave asked about what other libraries are doing here. Exposing the group on the event object seems strictly additive and something we could consider doing later, but figuring out what other event libraries do seems worthwhile to do before we continue. If anyone wants to take that on it'd be appreciated. |
(Exposing the group on the event object is basically a subset of #501.) |
I suggest we close this now that you can use abort signals as grouping mechanism thanks to @benjamingr's work. Thoughts? |
That sounds reasonable to me |
Reportedly when writing components it would be convenient to be able to remove a whole swatch of event listeners through a common identifier, rather than having to enumerate all the specific types and callbacks.
I have discussed this a long time ago with @wycats I believe and more recently with @RByers. Now that
addEventListener()
supports a dictionary we could make this a reality. E.g.,An alternative to overloading
obj.removeEventListener()
would be adding something likeobj.removeEventListenerClass("clicker")
, but that seems less extensible.The text was updated successfully, but these errors were encountered: