I'm working with a customElement using Shadow DOM like:
<hello-there><b>S</b>amantha</hello-there>
And the innerHTML (generated by lit/lit-element in my case) is something like:
<span>Hello <slot></slot>!</span>
I know that if const ht = document.querySelector('hello-there')
I can call .innerHTML
and get <b>S</b>amantha
and on the shadowRoot for ht, I can call .innerHTML
and get <span>Hello <slot></slot>!</span>
. But...
The browser essentially renders to the reader the equivalent of if I had expressed (without ShadowDOM) the HTML <span>Hello <b>S</b>amantha!</span>
. Is there a way to get this output besides walking all the .assignedNodes
, and substituting the slot contents for the slots? Something like .slotRenderedInnerHTML
?
(update: I have now written code that does walk the assignedNodes and does what I want, but it seems brittle and slow compared to a browser-native solution.)
class HelloThere extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({mode: 'open'});
shadow.innerHTML = '<span>Hello <slot></slot>!</span>';
}
}
customElements.define('hello-there', HelloThere);
<hello-there><b>S</b>amantha</hello-there>
<div>Output: <input type="text" size="200" id="output"></input></div>
<script>
const ht = document.querySelector('hello-there');
const out = document.querySelector('#output');
</script>
<button onclick="out.value = ht.innerHTML">InnerHTML hello-there</button><br>
<button onclick="out.value = ht.outerHTML">OuterHTML hello-there</button><br>
<button onclick="out.value = ht.shadowRoot.innerHTML">InnerHTML hello-there shadow</button><br>
<button onclick="out.value = ht.shadowRoot.outerHTML">OuterHTML hello-there shadow (property does not exist)</button><br>
<button onclick="out.value = '<span>Hello <b>S</b>amantha!</span>'">Desired output</button>