I have created a web component, and would like to access the elements from within the component.
Am using .attachMode({mode:'closed'}), so the parent has no access.
<template id='hello-world-template'>
<span id='inside'>Unchanged,</span> <span id='outside'>Unchanged</span>
<script>
document.querySelector('#inside').innerHTML = 'Changed';
// Ideal, but does not work - no such element
</script>
</template>
<hello-world></hello-world>
<script>
customElements.define('hello-world',
class extends HTMLElement {
constructor() {
super();
var template = document.getElementById('hello-world-template')
var clone = template.content.cloneNode(true)
const shadowRoot = this.attachShadow({mode: 'closed'}).appendChild(clone);
}
connectedCallback() {
this.shadowRoot.querySelector('#outside').innerHTML = 'Changed';
// Not ideal, and also does not work - this.shadowRoot has no querySelector
}
});
</script>
Some attempts:
- Within the document fragment - this, self, window, and document all refer to the parent window. And none can access the shadow root.
- Tried to store the shadowroot in a global variable and access it from inside the fragment or connectedCallback.
Even if that worked, it would defeat the point of using {mode:'closed'}, but anyways it did not work.
I have a hack that works, but cannot imagine that I have to use it.
The whole point of encapsulation is that things can be self contained, but what good does that do us if the JS cannot act on the other items in its container?
If this is the solution, would love a tip to explain the logic of the way components where implemented.
Here's the hack, though: include an image that runs the JS onload.
<template id='hello-world-template'>
<span id='inside'>Unchanged,</span> <span id='outside'>Unchanged</span>
<script>
function runner(img){
let doc = img.parentNode;
doc.querySelector('#inside').innerHTML = 'Changed';
}
</script>
<img src='data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=' onload="runner(this)">
</template>
<hello-world></hello-world>
Note regarding similar questions (25048359, 16633057, 55101967, etc.) - those answers will not work when mode is closed, which I need.