自定义元素上的 QuerySelector

QuerySelector on a Custom Element

我想select id='home-i' 的图标,并给出点击效果;但是,当我使用 document.querySelector('left-navbar nav'); 时,它 returns 为 null。我正在使用基本的 javascript 自定义元素,这似乎是导致问题的原因。

我已经尝试使用 shadowRoot 并使用 中所示的 setTimeout 技巧。这两种方法似乎都不起作用。

<left-navbar></left-navbar> 是自定义元素。

  <body>
        <main>
            <!-- Heading -->
            <h1 id='reading-heading'>Chapter 1</h1>

            <!-- Navigation Bar -->
            <left-navbar></left-navbar>

自定义组件

class Navbar extends HTMLElement {
    connectedCallback() {
        setTimeout(() => {
            this.innerHTML = `
            <nav id='navbar'>
                <i class="fas fa-home" id='home-i'></i>
                <hr class="line">
                <i class="fas fa-arrow-alt-circle-left" id='back-i'></i>
                <i class="fas fa-brain"></i>
                <i class="fas fa-lightbulb" id='quiz-i'></i>
                <i class="fas fa-sign-out-alt" id='exit-i'></i>
            </nav>
            `
        });
    }
}
customElements.define('left-navbar', Navbar)

Javascript 使用查询 select 或

const homeBtn = document.querySelector('left-navbar nav');

homeBtn.addEventListener('click', () => {
    window.location.href = 'index.html';
    changePageTitle(0);
})

setTimeout 使其函数在 事件循环被清除后执行,
所以所有其他JS代码被解析之后。

看下面代码,控制台显示other code,然后显示setTimeout

因此当试图添加点击处理程序时,HTML无法使用querySelector上。

如果单击处理程序绑定到 Web 组件,则将单击处理程序添加到 Web 组件内部

<script>
  customElements.define("my-element", class extends HTMLElement {
    connectedCallback() {
      setTimeout(() => console.log("setTimeout"));

      this.innerHTML = `<nav>Element Nav InnerHTML</nav>`;
      this.querySelector("nav").onclick = (evt) => alert("clicked!");
    }
  });
  console.log("other code");
  // your addEventListener was here
</script>

<my-element></my-element>

备注:

  • 如评论中所述,当您想要 阅读 innerHTML 中的 Web 组件 innerHTML 时,需要 setTimeout =];因为 connectedCallbackopening 标签上触发,所以它的内部 HTML 还没有被解析。 setTimeout 在所有 DOM 和(内联)JS 被解析之后执行。
    深入研究 SO post

  • 我在这里使用 inline onclick 事件侦听器; addEventListener 适用于您(可能)想要在一个 DOM 元素上添加多个侦听器的用例。
    参见:addEventListener vs onclick

  • 您还可以这样做:this.onclick = (evt) => alert("clicked!");