自定义元素上的 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);
)
【问题讨论】:
您确定要在添加<nav>
元素后添加事件侦听器吗?
为什么要使用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
;因为connectedCallback
在opening 标记上触发,所以它的innerHTML 还没有被解析。 setTimeout
在解析完所有 DOM 和(内联)JS 后执行。
深入了解this SO 帖子
我在这里使用 inline onclick
事件监听器; addEventListener
适用于您(可能)想要在一个 DOM 元素上添加多个侦听器的用例。
见:addEventListener vs onclick
你也可以这样做:this.onclick = (evt) => alert("clicked!");
【讨论】:
以上是关于自定义元素上的 QuerySelector的主要内容,如果未能解决你的问题,请参考以下文章