自定义元素上的 QuerySelector

Posted

技术标签:

【中文标题】自定义元素上的 QuerySelector【英文标题】:QuerySelector on a Custom Element 【发布时间】:2021-12-25 02:26:02 【问题描述】:

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

我尝试过使用 shadowRoot 和 setTimeout 技巧,如 this post 所示。这两种方法似乎都不起作用。

<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

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

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

【问题讨论】:

您确定要在添加&lt;nav&gt; 元素后添加事件侦听器吗? 为什么要使用setTimeout() 来添加innerHTML? 我试图遵循该链接中的建议。我打算获取自定义元素的内容,这正是我想要做的。 对于本质上是返回由模板字符串形成的 HTML 的函数而言,自定义元素似乎有点矫枉过正。 如果我对另一个问题的理解正确,那么只有在您尝试读取元素的innerHTML 时才需要这样做。 【参考方案1】:

setTimeout 使其函数在 EventLoop 被清除后执行, 所以之后所有其他的JS代码都被解析了。

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

因此,当尝试添加 Click 处理程序时,还没有可以使用 querySelector 的 HTML。

如果单击处理程序绑定到 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>

注意事项:

如 cmets 中所述,当您想要阅读connectedCallback 中的Web 组件innerHTML 时,需要setTimeout;因为connectedCallbackopening 标记上触发,所以它的innerHTML 还没有被解析。 setTimeout 在解析完所有 DOM 和(内联)JS 后执行。 深入了解this SO 帖子

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

你也可以这样做:this.onclick = (evt) =&gt; alert("clicked!");

【讨论】:

以上是关于自定义元素上的 QuerySelector的主要内容,如果未能解决你的问题,请参考以下文章

在Polymer中调用自定义元素/铁页面上的公共方法

vuetify 插件 2021 上的未知自定义元素 Vue Jest 测试 - Vue Cli 2

自定义指令的参数

从 Xamarin 表单元素共享代码访问自定义渲染器实例

NavigationDrawer 上的自定义字体

苗条打字稿上的苗条自定义事件