Skip to content

Make it possible to observe connected-ness of a node #533

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

Open
rniwa opened this issue Nov 4, 2017 · 66 comments
Open

Make it possible to observe connected-ness of a node #533

rniwa opened this issue Nov 4, 2017 · 66 comments
Labels
addition/proposal New features or enhancements

Comments

@rniwa
Copy link
Collaborator

rniwa commented Nov 4, 2017

It would be useful to have a way of observing when a node gets connected or disconnected from a document similar to the way connectedCallback and disconnectedCallback work for custom elements but unlike those at the end of the microtask like all other mutation records.

@rniwa
Copy link
Collaborator Author

rniwa commented Nov 4, 2017

@smaug---- @justinfagnani

@domenic
Copy link
Member

domenic commented Nov 4, 2017

It wasn't clear from the original thread what the use cases were. @pemrouze just said it would be nice, then people started discussing how. We never even talked about why they couldn't use custom elements.

I agree that if we had a need for this ability extending MutationObserver would be the way forward but I'd like some more justification in the form of concrete use cases that are hard to accomplish with custom elements.

@rniwa
Copy link
Collaborator Author

rniwa commented Nov 4, 2017

Agreed. It's always good to have a list of concrete use cases before adding new API.

@smaug----
Copy link
Collaborator

IIRC this was discussed around the time when MutationObserver was designed and the idea was that since one can add childList observer to the document and then just check document.contains(node), that should in principle be enough (and the things to observe was kept in minimum).
However Shadow DOM wasn't really a thing at that time, and that may have changed the needs.
Concrete use cases, which can't be solved with Custom Elements, would be indeed nice.
The more we add APIs, the more complicated platform we have to maintain and adding more and more API tends to slow down implementations, or at least makes it harder to optimize them.

@justinfagnani
Copy link

This would be useful for polyfilling custom elements, but obviously that's not a good use case for why custom elements aren't enough.

If I can page in my requests around MutationObservers one had to do with observing access shadow boundaries so we don't have to patch attachShadow, which might be relevant here, and have some way of unobserving nodes outside of disconnect(), say when the nodes are disconnected.

@pemrouz
Copy link

pemrouz commented Nov 4, 2017

It wasn't clear from the original thread what the use cases were. @pemrouze just said it would be nice, then people started discussing how. We never even talked about why they couldn't use custom elements.

  • A framework that does some housekeeping when a component is removed (e.g. tearing down subscriptions). The framework is outside the component, so would have to rely on every component emitting this event manually which isn't feasible/reliable. The disconnectedCallback is the current solution, but it requires wrapping every component in a wrapper component. This has other benefits (e.g. dynamic registry), but the less that can be done at the framework level would be great and this seemed generic enough to enquire about.

  • It would be nice for a component to be able to declaratively manage subscriptions it's own subscriptions, rather than have to emit the event manually or be forced to imperatively manage the subscription (see original thread).

@smaug----
Copy link
Collaborator

Wouldn't a childList observer in document take care of those use cases, at least in common cases?

@pemrouz
Copy link

pemrouz commented Nov 5, 2017

It's unfortunately notoriously difficult to do with MutationObserver, and pretty much guaranteed to be buggy (due to it being batched) and inefficient (having to watch every change on the entire document).

@WebReflection
Copy link

WebReflection commented Nov 8, 2017

This would be useful for polyfilling custom elements

polyfills for custom elements already work and are either based on MutationObserver or DOMNodeInserted/DOMNodeRemoved with a lookup for registered elements in the list of changed nodes.

Using polyfills is a weak reason, specially because anythig new needs to be polyfilled too.

However I do have a use case in hyperHTML too but I believe React and many other frameworks would love this feature as well.

CustomElements mechanism to understand their life-cycle are excellent but not everyone writes Custom Elements based sites and knowing a generic form, input, list element, grid card, has been added/removed would be ace.

in hyperHTML I do have control of each vanilla DOM component but I need to do this "dance" per each MutationObserver notification:

function dispatchTarget(node, isConnected, type, e) {
    if (components.has(node)) {
      node.dispatchEvent(e || (e = new Event(type)));
    }
    // this is where it gets a bit ugly
    else {
      for (var
        nodes = node.children,
        i = 0, length = nodes.length;
        i < length; i++
      ) {
        e = dispatchTarget(nodes[i], isConnected, type, e);
      }
    }
    return e;
  }

The dispatching after recursive search is done per each record.addedNodes and record.removedNodes but if I had a platform way to loop over all known connected/disconnected nodes my code, and my life, would definitively be easier.

@pemrouz
Copy link

pemrouz commented Dec 19, 2017

@domenic any more thoughts?

@rniwa
Copy link
Collaborator Author

rniwa commented Feb 17, 2018

Here's a concrete use case. A editor library wants to know when the editor lost the focus. Because blur event does not fire on an element that got disconnected from a document before losing the focus, we'd need to monitor when the element is disconnected. To do this, we currently need to monitor all child node changes of the parent node, and then detect when the editor node is removed. With the proposed observation type, we can observe the disconnection of the editor element instead.

@WebReflection

This comment was marked as off-topic.

@smaug----

This comment was marked as resolved.

@rniwa

This comment was marked as resolved.

@WebReflection

This comment was marked as off-topic.

@rniwa

This comment was marked as resolved.

@wessberg
Copy link

wessberg commented Jul 17, 2018

Yes, this is much needed indeed.
Tracking when elements are connected/disconnected is rather easy with MutationObservers when not using Shadow DOM, but with it and as I see it, we have to observe the childList of the root of all parents going recursively up the tree from the node in question. The parent chain of the node may change or the node may have no parent(s) by the time the MutationObservers are configured, so this won't even fully solve the problem. Looking back at MutationEvents, from my own testing, DOMNodeRemovedFromDocument doesn't seem to fire if a child element is indirectly removed from the DOM if it is located within the ShadowRoot of another host element that is disconnected.

I have a concrete use case for progressive enhancement that is much inspired by the Custom Attributes proposal that was discussed a while back and I've brought into a user-land library. Custom Attributes are sort of like is, except they can annotate any element, receive values, and implement the Custom Elements lifecycle hooks for it. Think of it as decorators for HTML, or behaviors.

For example:

// Listens for PointerEvents and paints Material Design Ripples on the host element
class Ripple {
    constructor (hostElement) {...}
    connectedCallback () {...}
    disconnectedCallback () {...}
    // ...
}
customAttributes.define("*ripple", Ripple);
<!-- Custom Attributes are element-agnostic -->
<button *ripple>Click me</button>
<!-- They can also receive semi-colon separated key-value pairs as values, just like the style attribute -->
<my-element *ripple="center: true"></my-element>

Now, while I would like to see Custom Attributes/mixins/behaviors standardized since is for Customized Built-In Elements isn't agnostic of host elements, that is a discussion for another place, but nevertheless it shows a concrete use case.

To solve this today, using MutationObservers just doesn't cut it when using Shadow DOM. There may be many, changing, roots going up the tree from the node, or there may be none at all! You can observe child lists of all roots and hosts from the node and up the tree, but you have to do a lot of work to track changes to the parent chain and update the observers. But if the node has no parent by the time the MutationObserver needs to be configured, you will never know which root to observe.

The "best" way to do this right now (as I see it) is monkey patching the Node and Element prototypes, similar to what the Polymer team does in the Custom Elements polyfill, and then check connection states of affected notes within those operations. For anything else than polyfills, I think this is bad for performance, and it is synchronous, something MutationObservers were designed in part to avoid, and basically just something to be avoided if possible. Which is why I'm strongly rooting for extending MutationObserverOptions with a connectionState property or something like it. That way, the asynchronous nature is preserved and monkey patching is avoided.

@caridy
Copy link

caridy commented Jan 30, 2019

I would like to revamp this conversation. It seems that we have more use-cases that can help us to come to an agreement about this feature request. Maybe adding it to the agenda for the F2F meeting.

@rniwa
Copy link
Collaborator Author

rniwa commented Jan 31, 2019

Yeah, I think we should just add this. Here's a concrete proposal:

Add boolean connectedness to MutationObserverInit, which if set would make the mutation observer start receiving a mutation record whenever the target node is connected to or disconnected from a document.

Add two mutation record types connected and disconnected to MutationRecord. connected is used the target node is newly connected to a document. disconnected is used when the target node has been is newly removed from a document.

subtree option in mutation observer would the observation subtree-wide.

@wessberg
Copy link

Sounds great. Wouldn't it be sufficient with a simple boolean connected which is true|false?

@rniwa
Copy link
Collaborator Author

rniwa commented Jan 31, 2019

Sounds great. Wouldn't it be sufficient with a simple boolean connected which is true|false?

Sorry, I wasn't thinking through. We could just add new mutation record types like connected / disconnected and not even add a boolean. Updated the proposal accordingly.

@annevk annevk added the addition/proposal New features or enhancements label Jan 31, 2019
@trusktr
Copy link

trusktr commented Feb 1, 2019

We never even talked about why they couldn't use custom elements.

@domenic The main use case I imagine is with builtins, so we can get connected/disconnected behavior that behaves the same as the callbacks for Custom Elements do. (I didn't see this thread before I wrote WICG/webcomponents#785)

It'd be useful in some of the other issues I've had troubles with too.

It's always good to have a list of concrete use cases before adding new API.

@rniwa Another use case is simply: someone else made a web app, now we want to manipulate it without necessarily touching their source code (maybe we don't have access to the source, maybe we are writing a browser plugin, etc). There's still the issue of reaching into closed shadow trees though (it still requires patching attachShadow).

In a sense the purpose of this feature is more similar to the purpose of jQuery: manipulate existing DOM elements with it. This is in contrast to the act of designing the behaviors of our own DOM elements (custom elements), instead we can use this to manipulate existing DOM elements (builtin or custom).

👍 to this.

@jfbrennan
Copy link

jfbrennan commented Jan 12, 2024

Just want to add my use case:

<template>
  <p>My Custom Element with a menu</p>
  <button onclick="toggleMenu">Toggle</button>
  <x-menu>...</x-menu>
</template>

That template gets used in a Custom Element where I also call a utility function that takes the custom element as its one param, searches all its children looking for any onevent attributes which came from the template, and replaces them by registering an event listener - element.addEventListener('click', e => this.toggleMenu(e)) - and removes the event property. In other words, template event binding.

I'd like this utility function to also remove the listeners when the custom element is disconnected. If the utility class had a way to know when the custom element was disconnected that would be possible. Right now I have to return the collection of event registrations to the custom element and it runs through that list in its disconnectedCallback.

@LeaVerou
Copy link

Not sure if it has been suggested, but one way to make this plus a few more use cases easier would be to add an option to monitor parent changes. It's simpler than the original problem, and in some ways more general.
It would still be annoying to monitor connected-ness, but a lot less so (a utility function instead of a whole library).

@FrameMuse
Copy link

FrameMuse commented Feb 22, 2025

Use case

I guess the main use case would be removing subscriptions. In my case, I have a (library based) "component" that saves reference to a constructed element, the component must support callbacks for engaging scripts when the element is connected and pause/suspend those scripts when it's disconnected.

In reality, it's a bit more complex since an element may not be disconnected while actually not being in the document. So it should take into account connection/disconnection from a document (either parents or the element itself is connected/disconnected).

For accurate work, when #1255 is implemented, the document connection events should fire or they should be accounted by a developer.

Implementation Proposal

I see it as a separate NodeLifeObserver class, based on MutationObserver, IntersectionObserver signature. Though this also might be worth adding dispatched events (addEventListener).

type NodeLifeEntryCase =
  | "connected"
  | "disconnected"

//  | "parentChanged" // or `reparented`.
//  | "parentConnected"
//  | "parentDisconnected"

//  | "documentConnected"
//  | "documentDisconnected"

interface NodeLifeEntry {
  target: Node
  case: NodeLifeEntryCase
}

class NodeLifeObserver {
  constructor(callback: (entry: NodeLifeEntry[], observer: NodeLifeObserver) => void) { }

  observe(node: Node): void
  unobserve(node: Node): void
  disconnect(): void
}

The commented out entry cases are debatable, but for simplicity I agree we can start from just connected + disconnected and that's it.


Alternative Interface

IMHO, this is more restrictive one, it might be difficult to add new connection types if needed, though if we all agree on it - I don't mind.

interface NodeConnectionEntry {
  target: Node
  connected: boolean
}

class NodeConnectionObserver {
  constructor(callback: (entry: NodeConnectionEntry[], observer: NodeConnectionObserver) => void) { }

  observe(node: Node): void
  unobserve(node: Node): void
  disconnect(): void
}

Why not ConnectionObserver? - It might be confused with (Network)Connection instead of (Node)Connection.


This is a potential extension for proposal above, but is NOT required.

Additionally I need the moment when is reflowed...

Additionally I need the moment when is reflowed since connection/disconnection may change the size, but you need to use this recalculated value. So I expect that e.g. connected event would occur before [relow](reflow - MDN Web Docs Glossary: Definitions of Web-related terms | MDN) and when it does occur, it would trigger additional reflowed event.

With this I come up with the following code that extends NodeLifeObserver for Element.

type ElementLifeEntryCase =
  | NodeLifeEntryCase
  | "reflow"


interface ElementLifeEntry {
  target: Element
  case: ElementLifeEntryCase
}

class ElementLifeObserver {
  constructor(callback: (entry: ElementLifeEntry[], observer: ElementLifeObserver) => void) { }

  observe(element: Element): void
  unobserve(element: Element): void
  disconnect(): void
}

Currently, the moment when a element is reflowed can be accurately caught with this snippet. Obviously, I would like to have a more general approach to receiving this event.

export function onElementPainted(target: Element, callback: () => void) {
  new ResizeObserver((_, observer) => {
    callback()
    observer.unobserve(target)
  }).observe(target)
}

@trusktr
Copy link

trusktr commented Apr 27, 2025

@FrameMuse unrelated to the original discussion, but it is actually impossible to detect when an element is finally painted:

Currently, the moment when a element is reflowed can be accurately caught with this snippet. Obviously, I would like to have a more general approach to receiving this event.

export function onElementPainted(target: Element, callback: () => void) {
new ResizeObserver((_, observer) => {
callback()
observer.unobserve(target)
}).observe(target)
}

That's not good enough because if some other resize observer callback changes the size (directly or indirectly) of the element, it is possible that more resize callbacks will subsequently be queued and fired. The only sure thing we can do is keep the resize observer enabled the whole life of the element, instead of unobserving it right away, otherwise some reflows may be missed.

But note that reflow is not the same as paint, and it is impossible to run logic after paint. The "paint" doesn't happen until after all resize observer callbacks, and it is impossible to register a callback that will run after all ResizeObserver callbacks are finished.

See these issues for more on the impossible timing, problems, and solution ideas:

@trusktr
Copy link

trusktr commented Apr 27, 2025

type NodeLifeEntryCase =
| "connected"
| "disconnected"

| "parentChanged" // or reparented.
| "parentConnected"
| "parentDisconnected"

| "documentConnected"

What's the need for parentConnected (and the other parent hooks) vs the connected/disconnected? Is it that you want to run logic when an element is connected/disconnected in an inert tree that is not in the DOM? If so, I'm not sure that this is a good idea: for example the content of a <template>'s .content document is meant to be inert and we should avoid running logic on those trees. The idea is that when a element is connected into the live DOM (connected), that's when we load stuff.

Also, from the perspective of designing something simple enough for everyone to get on board with, maybe having all of that in a single proposal is too much. Could you trim down your proposal to only this,

type NodeLifeEntryCase =
| "connected"
| "disconnected"

without the other hooks, and without ElementLifeObserver? We could always expand on something later, but trying to get something like that all in at once (including ElementLifeObserver) would be too difficult I think. They're not bad ideas (my previous comment links to much needed similar API ideas for observing style/reflow/etc), just that we may have a better time making focused incremental changes.

@trusktr
Copy link

trusktr commented Apr 27, 2025

I want to point out that having an API for synchronous element connectedness (from the outside, not limited to internal custom element methods) will help solve brain-twisting problems like this one:

@trusktr
Copy link

trusktr commented Apr 27, 2025

Just to clarify the OP:

similar to the way connectedCallback and disconnectedCallback work for custom elements but unlike those at the end of the microtask

Is this describing a synchronous API (not an async API like MutationObserver which runs callbacks in a microtask)?

If so, that's what I want. A synchronous API. (We already have MutationOberver for async).

An idea could be to expand MutationObserver options like this:

myMutationObserver.observe(el, {
  // ...other options as usual...,

  async: false, // new option
})

@rniwa
Copy link
Collaborator Author

rniwa commented Apr 27, 2025

Just to clarify the OP:

similar to the way connectedCallback and disconnectedCallback work for custom elements but unlike those at the end of the microtask

Is this describing a synchronous API (not an async API like MutationObserver which runs callbacks in a microtask)?

No. The API request here is like other mutation observer callbacks and only happens at the end of a current microtask.

@wessberg
Copy link

wessberg commented Apr 27, 2025

@trusktr
Whether to design a synchronous or asynchronous solution has been a discussion point and likely one of the main reasons why we haven't been able to move forward in any direction so far.

I for one have argued for an asynchronous approach, partly because we know from the past how MutationEvents was shipped and later unshipped from browsers due to concerns among browser implementers about their synchronous nature.

There are several reasons why observing the connectedness of any node is not trivially solved with Mutation Observers, in part because a Node may move between roots in the DOM tree. Listening for changes to child lists across every existing and future Shadow Root in the document just to track a Node is not ideal, and at least my primary motivation for wanting to see this eventually being solved by observing the node itself.

@ydaniv
Copy link

ydaniv commented Apr 28, 2025

We have a use-case for this feature, probably more of the same, but the ability to directly watch the connectedness of an element is the only feature we're missing. We have an interactions library that's agnostic to the rest of the code, and especially to frameworks, which may alter the DOM.
Since not everything is yet (or ever) possible with CSS, everything the library touches must be observed.
Currently we have to wrap every element that takes part with a custom element just for this end.

@dead-claudia
Copy link

Whether to design a synchronous or asynchronous solution has been a discussion point and likely one of the main reasons why we haven't been able to move forward in any direction so far.

I for one have argued for an asynchronous approach, partly because we know from the past how MutationEvents was shipped and later unshipped from browsers due to concerns among browser implementers about their synchronous nature.

Will note that while notification is asynchronous, subscription and disconnect is synchronous. And the .unobserve(elem) proposal here is as synchronous as .observe(elem).

@wessberg
Copy link

@dead-claudia yes, thanks for clarifying this to prevent potential misunderstandings. I'm fully aligned with that, and I think there is strength in that it follows the same design principles as existing observers such as MutationObserver, ResizeObserver, and IntersectionObserver.

E.g. something like this would be ideal to me:

const observer = new ConnectionObserver(entries => {
	for (const {connected, target} of entries) {
		console.log("target:", target);
		console.log("connected:", connected);
	}
});

// Observe 'someElement' for connectedness (synchronous)
observer.observe(someElement);

// Eventually disconnect the observer (synchronous)
observer.disconnect();

I made a little proof of concept of that here, which works well, but requires patching Element.prototype.attachShadow, which is unfortunate.

@FrameMuse
Copy link

@trusktr After I published the proposal of mine I thought about it for some longer and I agree that there is less sense in listening for parent connection. I will edit my proposal, while it actually still makes sense to listen for parent connection if we don't have #736 resolved.

@FrameMuse
Copy link

@wessberg That's just awesome man! Nice poc, thank you so much

@LeaVerou
Copy link

Why would we need a separate observer for connectedness? It seems to fit right in the scope of MutationObserver.

@FrameMuse
Copy link

@LeaVerou Good question, I have an example demonstrating the complications, I will share it when prepared.

@justinfagnani
Copy link

It seems pretty straightforward and web-compatible to me to add a new connection: boolean property to MutationObserver.observe() options, when when true enables a new MutationRecord type of connection.

@dead-claudia
Copy link

Why would we need a separate observer for connectedness? It seems to fit right in the scope of MutationObserver.

Simply doing .observe(document.documentElement, {childList: true, subtree: true}) and similar for shadow roots is sufficient for detecting connectedness changes. And that paired with a weak map would even let you put together your own unsubscribe mechanism.

This code implements liveness observers for all but children of declarative shadow roots:

let observeShadow
const observers = new Set()
const registry = new FinalizationRegistry(held => {
    observers.delete(held)
})
const oldAttachShadow = Element.prototype.attachShadow
Object.defineProperty(Element.prototype, "attachShadow", {
    value() {
        const root = oldAttachShadow.apply(this, arguments)
        for (const weak of observers) {
            const observer = weak.get()
            if (observer) observeShadow(observer, root)
        }
        return root
    },
})

class LivenessObserver {
    #callback
    #observed = new WeakSet()
    #observer = new MutationObserver(records => {
        this.#check(records)
    })

    static {
        observeShadow = (observer, root) => {
            observer.#observer.observe(root, {
                childList: true,
                subtree: true,
            })
        }
    }

    constructor(callback) {
        this.#callback = callback
        observeShadow(this.#observer, document.documentElement)
        const weak = new WeakRef(this)
        observers.add(weak)
        registry.register(this, weak)
    }

    #check(records) {
        for (const r of records) {
            for (const n of r.removedNodes) {
                if (!this.#observed.has(n)) continue
                try {
                    this.#callback.removed?.(n)
                } catch (e) {
                    reportError(e)
                }
            }

            for (const n of r.addedNodes) {
                if (!this.#observed.has(n)) continue
                try {
                    this.#callback.added?.(n)
                } catch (e) {
                    reportError(e)
                }
            }
        }
    }

    observe(node) {
        this.#observed.add(node)
    }

    disconnect() {
        this.#observed.clear()
    }
}

Will note that this is probably not as fast as it could be.

@dead-claudia
Copy link

Back to the original feature request, I propose a minimal compromise: add a liveness: true flag to MutationObserver.

Chromium, Firefox, and Safari all three track this via a bit flag on the node itself. And it already needs recursively checked anyways to invoke custom element reactions, so it's not hard to just add a stack of mutation observers to possibly invoke with each node during the pass.

Unobserving nodes is better discussed in #126. Please, let's keep this on-topic, to avoid spamming everyone's notifications. (I'll admit some fault in contributing to the problem.)

@FrameMuse
Copy link

FrameMuse commented Apr 30, 2025

@justinfagnani Maybe I got you wrong, is this how it should work?

const observer = new MutationObserver(entries => console.log(entries[0].connection))

const node = new Text("123")
observer.observe(node, { connection: true })

document.body.append(node) // => true
node.remove() // => false

Then I disagree. I personally think that connection is not mutation of a connected node (but a parent or document), it would be ambiguous to add it this way. The current MutationObserver is very on point - observe listed mutations OF these nodes. But in case of adding connection option, it goes a long way: observe mutations of all nodes, to tell if this is related to the observed node and see if it's connected or not.

So if it's already doing childList and subtree anyway, why making it ambiguous if we can introduce a new thing that just extends MutationObserver?


Ofc, this is not a crucial discussion, so if it's easier to implement any other way - ok.
I just want things to be more accessible


And I agree we first need to get some use-cases and application examples listed before thinking much about APIs.

@dead-claudia
Copy link

dead-claudia commented Apr 30, 2025

@FrameMuse His connected ≈ my liveness. I noted that browsers in practice track it via a bit.

And connection is a direct consequence of mutations, just not of the element itself. Consider that connection is when iframes and images start their initial load.

@FrameMuse
Copy link

FrameMuse commented Apr 30, 2025

@dead-claudia

And connection is a direct consequence of mutations

just not of the element itself

I guess this is what makes it indirect. This is what I was referring to - indirect mutation observing.

Consider that connection is when iframes and images start their initial load.

I don't think the connection events should fire when HTML is parsed, only when connections done to existing DOM in memory.

@dead-claudia
Copy link

Consider that connection is when iframes and images start their initial load.

I don't think the connection events should fire when HTML is parsed, only when connections done to existing DOM in memory.

@FrameMuse I'm talking about script-created elements here. These are called on dynamic insertion as well as during initial HTML tree building. And here's the part for iframes I was referring to.

I'm also expressly just asking for a way to observe that in-practice browser bit flag, so while in theory it's indirect, it in practice is very much direct observation of a node's mutable state.

@jamesdiacono
Copy link

Could Nodes simply emit non-bubbling "connect" and "disconnect" events? That would let us do everything that currently requires connectedCallback and disconnectedCallback.

@wessberg
Copy link

wessberg commented May 1, 2025

@jamesdiacono

We've been down that path before with MutationEvents which caused many issues and was later unshipped from browsers.

Instead I think we may be able to achieve consensus that adding a connected (or similar wording) to MutationObserver is the way forward? Based on recent discussion in this thread it seems like the approach most favored. And I'm also leaning towards agreeing that its better than my original idea of a dedicated observer.

@FrameMuse
Copy link

@dead-claudia Yeah, it depends how you think about it. So let's say we both understand each other. I'm just saying adding ~connected to MutationObserver is not immediately natural, but it'd be still very quick to adapt and get used to.

@wessberg I don't really mind for now, we can think about better place after it's shipped to browsers and countless experiments.

@FrameMuse
Copy link

@jamesdiacono AFAIK, Events have different scheduling comparing to MutationObserver and they have many more properties than MutationObserver, they might be useful, but as this topic is already associated with MutationObserver, which historically had a problematic version of MutationEvent - seems olds won't accept something related to go this path again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements
Development

No branches or pull requests