如何为Web Component的Shadow DOM内h3元素接入随机变色JS函数
问题根源
全局的document.querySelector只能查询页面普通DOM树里的元素,Web Component的Shadow DOM是隔离的,全局查询API无法直接访问到Shadow DOM内部的节点,所以你原来的写法只能修改全局的Sentence 1的h3颜色,碰不到组件内部的Sentence 2的h3。
推荐解决方案(组件内封装逻辑,符合Web Component封装原则)
直接把变色逻辑写到UserCard自定义类内部,用组件实例的shadowRoot来查询内部的h3元素,修改后的JS代码如下:
const template = document.createElement('template'); template.innerHTML = ` <style> h3 { color: coral; } </style> <h3>Sentence 2 </h3> `; class UserCard extends HTMLElement { constructor() { super(); this.attachShadow({mode: 'open'}); this.shadowRoot.appendChild(template.content.cloneNode(true)); this.colorArr = ['#FFD640', '#fdff76', '#f0cd59', '#fa9624', '#fa6824', '#a33f11']; this.colorTimer = null; } // 组件挂载到DOM时触发 connectedCallback() { const innerH3 = this.shadowRoot.querySelector('h3'); this.colorTimer = setInterval(() => { innerH3.style.color = this.colorArr[Math.floor(Math.random() * this.colorArr.length)]; }, 1000); } // 组件从DOM移除时触发,清理定时器避免内存泄漏 disconnectedCallback() { if(this.colorTimer) clearInterval(this.colorTimer); } }; window.customElements.define('user-card', UserCard);
这种方案不需要额外调用外部函数,组件加载完成后会自动运行变色逻辑。另外你原来的颜色数组第一个值多了个多余的分号,已经删掉了,原来代码里没用的num变量也直接移除了。
可选方案(保留外部changeColor函数)
如果确实需要把变色逻辑放在组件外部,修改changeColor里的查询逻辑即可:
function changeColor() { const arr = ['#FFD640', '#fdff76', '#f0cd59', '#fa9624', '#fa6824', '#a33f11']; // 先拿到自定义组件实例,再访问它的shadowRoot查询内部h3 const innerH3 = document.querySelector('user-card').shadowRoot.querySelector('h3'); setInterval(function () { innerH3.style.color = arr[Math.floor(Math.random() * arr.length)]; }, 1000); } // 要确保自定义组件已经注册渲染完成后再调用changeColor window.addEventListener('DOMContentLoaded', changeColor);
内容的提问来源于stack exchange,提问作者Андрей Романов
相关产品推荐
相关产品推荐

