自定义Web组件constructor调用getAttribute返回null但attributes可见问题
问题原因
- 自定义元素构造函数执行时,元素仅完成实例初始化,尚未插入DOM树,HTML上声明的属性还未同步到元素实例,因此
getAttribute、hasAttribute无法读取到属性。 - 控制台打印
this和this.attributes时展示的是引用对象的最终状态:你手动展开控制台打印结果时,元素已经完成DOM挂载、属性已经同步,所以能看到属性存在,这不是代码执行到打印语句那一刻的真实状态。
修复方案
将属性读取逻辑移动到connectedCallback生命周期钩子中,该钩子会在元素被正式插入DOM树后触发,此时属性已经完成同步,可以正常读取。
修改后的component.js代码:
const template = document.createElement('template'); template.innerHTML = `...`; class TestComponent extends HTMLElement { constructor(){ super(); this.attachShadow({mode: 'open'}); this.shadowRoot.appendChild(template.content.cloneNode(true)); } connectedCallback() { console.log(this); console.log(this.attributes); console.log(this.getAttribute('test1')); // 返回 Test-text console.log(this.hasAttribute('test1')); // 返回 true } } window.customElements.define('test-component', TestComponent);
扩展说明(可选)
如果需要动态监听属性值的变更,可以搭配observedAttributes静态属性和attributeChangedCallback钩子实现:
class TestComponent extends HTMLElement { // 声明需要监听变化的属性列表 static get observedAttributes() { return ['test1', 'test2']; } constructor(){ super(); this.attachShadow({mode: 'open'}); this.shadowRoot.appendChild(template.content.cloneNode(true)); } connectedCallback() { console.log(this.getAttribute('test1')); } // 监听的属性发生变化时自动触发 attributeChangedCallback(name, oldValue, newValue) { console.log(`属性${name}已更新:旧值${oldValue},新值${newValue}`); } } window.customElements.define('test-component', TestComponent);
内容的提问来源于stack exchange,提问作者Syntaxed
相关产品推荐
相关产品推荐

