-
Notifications
You must be signed in to change notification settings - Fork 316
Description
What problem are you trying to solve?
It's quite common to want to bind to event listeners on global objects, or parent objects to take advantages of delegate event listening. Doing so requires tearing down those listeners, which can be a little cumbersome.
What solutions exist today?
AbortController
makes this easier but it can still involve a fair amount of boilerplate; here's the minimum viable code to register an event listener with appropriate AbortController
code:
class MyElement extends HTMLElement {
#controller = null;
connectedCallback() {
this.#controller?.abort();
const signal = this.#controller = new AbortController();
this.ownerDocument.addEventListener('whatever', e => {}, {signal});
}
disconnectedCallback() {
this.#controller?.abort();
}
}
How would you solve it?
First proposal
I'd like to introduce an AbortSignal intrinsic to the CE lifecycle, one that gets automatically set up just before connectedCallback()
and gets aborted just before (or maybe just after?) disconnectedCallback()
. In doing so, the above code could become something like:
class MyElement extends HTMLElement {
#internals = this.elementInternals();
connectedCallback() {
const signal = this.#internals.connectedSignal();
this.ownerDocument.addEventListener('whatever', e => {}, {signal});
}
}
Whenever an element gets connected, it would abort and dispose of its associated connectedSignal, and create a new one. Calling this.#internals.connectedSignal()
would return the current associated connectedSignal. When an element disconnects from the DOM, it would abort its associated signal.
This would alleviate much of the work around creating and managing an AbortController
just to abstract the work of connectedCallback/disconnectedCallback.
I propose we add the following:
interface Node {
AbortSignal disconnectedSignal()
}
Calling disconnectedSignal()
returns a new AbortSignal
. When the Node is disconnected, it aborts all AbortSignal
s created via this method.
Anything else?
No response