Accessing the Theme Header and Footer in Javascript - Vanilla Success
<main> <article class="userContent"> <p>Once you've created a header and footer you may be wondering how run javascript on its contents.</p><p>Headers and Footers are isolated from the rest of the page in order to prevent styling conflicts. This is done using the <a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM" rel="nofollow noreferrer ugc">Shadow DOM</a>. This means a normal method of querying/modifying a DOM node won't work.</p><p>Don't worry though, all that's need is a minor modification.</p><h2 data-id="example-without-shadow-dom">Example without Shadow DOM</h2><p>Let's say we wanted to add a click event handler to a button in our header. Without a shadow DOM we would do it like this.</p><p><strong>header.html</strong></p><pre class="code codeBlock" spellcheck="false" tabindex="0"><header> <button type="button" id="headerButton">Click Me!</button> </header> </pre><p><strong>javascript.js</strong></p><pre class="code codeBlock" spellcheck="false" tabindex="0">onVanillaReady(function() { // Find the button. var button = document.querySelector("#headerButton"); if (button) { // Best to always check the your item was found. Otherwise you might crash the page. button.addEventListener("click", function (e) { alert("Button was clicked!"); }); } }); </pre><h3 data-id="why-doesn't-this-work">Why doesn't this work?</h3><p><code class="code codeInline" spellcheck="false" tabindex="0">document.querySelector</code> will not find any element because your button has been rendered inside of a shadow DOM. Let's see an example of how to make this work.</p><h2 data-id="working-example-with-shadow-dom">Working Example with Shadow DOM</h2><p><strong>header.html</strong></p><p>Same as above.</p><p><strong>javascript.js</strong></p><pre class="code codeBlock" spellcheck="false" tabindex="0">onVanillaReady(function () { // Get access to the root of the header. // THIS IS THE CHANGE var themeHeader = document.querySelector("#themeHeader").shadowRoot; // Find the button. var button = themeHeader.querySelector("#headerButton"); if (button) { // Best to always check the your item was found. Otherwise you might crash the page. button.addEventListener("click", function (e) { alert("Button was clicked!"); }); } }); </pre><p>All that was needed as a change was querying the shadow root of the header.</p> </article> </main>