Reputation: 19295
I am writing a chrome extension that modifies elements properties as a page is loaded or changes.
I do this using a Mutation Observer. However the observer's handler is not called when shadow-dom (ie, embedded twitter posts) are loaded/changed.
Is there a way to get an event when shadow-dom is loaded/changes or to hook a mutation observer to it ?
Thanks!
Upvotes: 6
Views: 6138
Reputation: 2544
if the contents are simply getting slotted using the slotchange
event is easiest, it doesn't fire on deeper changes, just the slotting (unlike a mutation observer watching a subtree and childList); it's like an observer of childList on the slot and the best way to separate concerns between a component and slotted content; when observing changes in a component's own respective shadowRoot
or deeper in a tree for some reason, use the mutation observer in @Supersharp's answer except adding subtree
to the config (or possibly setup children with their respective shadowRoots to dispatch an event with {composed: true, cancelable: true, bubbles: true}
notifying ancestors up to your component of the change;
there'd need to be a slot added to the shadowRoot and the event listener added to it like shadowRoot.innerHTML = <slot onslotchange=...>empty slot</slot>
adapted to work in-context
https://developer.mozilla.org/docs/Web/API/HTMLSlotElement/slotchange_event
Upvotes: 0
Reputation: 31181
You can simply observe()
the shadowRoot
property of the element with a Shadow DOM.
customElements.define('image-list', class extends HTMLElement {
connectedCallback() {
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
//Detect <img> insertion
if (mutation.addedNodes.length)
console.info('Node added: ', mutation.addedNodes[0])
})
})
this.attachShadow({mode: 'open'}).innerHTML = '<img alt="image 1">'
observer.observe(this.shadowRoot, {childList: true})
}
addImage() {
var img = document.createElement('img')
img.alt = ' new image '
this.shadowRoot.appendChild(img)
}
})
<image-list id=LI>
</image-list>
<button onclick="LI.addImage()">Add image</button>
Upvotes: 12