SCRIPT Scopes & (closed) shadowRoot references
by Danny Engelman
HTML
<H2>Access mode:closed Component from Template <script> ... see F12 console</H2>
<a href="https://stackoverflow.com/questions/60097743/access-element-from-within-shadow-dom">StackOverflow question (feb 2020)</a>
<hr>
<script>
let style_execution_count=0;
</script>
<template id='hello-world-template'>
<span id='inside'>Inside Unchanged,</span>
<span id='outside'>Outside Unchanged</span>
<script>
//console.log('execute <script> this:', this);
function templFunc(from = 'SCRIPT') {
try {
console.log('execute templFunc this:', from, this.component && this.component.id, this);
this.querySelector('#inside').innerHTML = this.component.id + 'Changed #inside from Template <script>';
this.component.Amethod('from template');
} catch (e) {
console.error('',e);
}
}
</script>
<style onload="console.warn('STYLE onload', ++style_execution_count)">
#inside {
color: green;
}
</style>
<!-- this.parentNode === this.getRootNode() .. unless IMG is nested! -->
<img src="" onerror="templFunc.call(this.getRootNode())">
</template>
<script>
customElements.define('hello-world',
class extends HTMLElement {
constructor() {
super();
let templ = document.getElementById('hello-world-template').content.cloneNode(true);
this.Root = this.attachShadow({
mode: 'closed' // mode:closed will force this.shadowRoot to null!!
});
this.Root.appendChild(templ);
console.log(this.nodeName, '.constructor() this.Root:', this.Root, this.shadowRoot);
this.Root.component = this; //make component available in Template script tag-function
}
connectedCallback() {
this.Root.querySelector('#outside').innerHTML = 'and #outside from connectedCallback';
this.Amethod('from connectedCallback');
try {
templFunc.call(this.Root, 'from connectedCallback');
} catch (e) {
...