原生JS Web Component中this.shadowRoot.querySelector一直返回null怎么办
问题原因分析
- 核心错误为
cloneNode方法的使用不符合规范:Node.cloneNode()仅接收1个布尔类型参数,用于指定是否执行节点深拷贝。你代码中错误调用了<template>元素本身的cloneNode方法,且错误传入模板内容对象content作为参数,最终追加到shadow root中的是<template>元素的拷贝,模板内部的<div>并未直接挂载到shadow DOM的可查询节点树中,因此直接调用querySelector('div')无法匹配到元素。 - 额外写法问题:constructor中
super()的调用不需要单独用变量存储返回值,Web Component规范要求constructor中先调用super()后可直接使用this操作当前组件实例。
修复方案
调整constructor内的模板克隆逻辑,直接克隆模板的content节点即可,修复后无需设置延迟定时器即可直接查询到内部元素,完整可运行代码如下:
<template id="TEMPLATE_UPLOADER"> <div>Try Query Me</div> </template> <script> customElements.define('my-uploader', class extends HTMLElement { constructor() { super(); const template = document.getElementById("TEMPLATE_UPLOADER"); const shadowRoot = this.attachShadow({mode: "open"}); // 直接克隆模板content的深拷贝,追加到shadow root shadowRoot.appendChild(template.content.cloneNode(true)); } connectedCallback() { // 修复后无需延迟,可直接调用init this.init(); } init() { const el = this.shadowRoot.querySelector('div'); console.log('获取到的元素:', el); // 可正常打印div元素 } }); </script> <my-uploader></my-uploader>
内容的提问来源于stack exchange,提问作者run_the_race
相关产品推荐
相关产品推荐

