this.getAttribute('attribute') 即使属性显示在 this.attributes 中也返回 null

this.getAttribute('attribute') returning null even though attributes showing in this.attributes

我正在创建一些 Web 组件并尝试从组件属性中提取数据。当我 console.log(this) 时,它显示正确的元素和关联的属性。和我 console.log(this.attributes) 时一样。但是,如果我 console.log(this.getAttribute('attribute')) 或 console.log(this.hasAttribute('attribute')) 我分别返回 null 和 false .

有人能理解这个吗?这是我正在使用的代码:

index.html

<script src="component.js"></script>

<test-component test1="Test-text" test2=""></test-component>

component.js

const template = document.createElement('template');

template.innerHTML = `...`;

class TestComponent extends HTMLElement {

    constructor(){
        super();
        this.attachShadow({mode: 'open'});
        const shadow = this.shadowRoot;
        shadow.appendChild(template.content.cloneNode(true));
        console.log(this); // Shows correct element with attributes
        console.log(this.attributes); // Shows attributes
        console.log(this.getAttribute('test1')); // Returns null
        console.log(this.hasAttribute('test1')); // Returns false

    }
}

window.customElements.define('test-component', TestComponent);

只有在 connectedCallback 中,您的 CE 才存在于 DOM 中。

constructor中它只是在内存中进行了预处理,你可以使用它的影子DOM,但是CE还没有在(main)DOM中,因此您无法访问属性。

customElements.define('test-component', class extends HTMLElement {
    constructor(){
        super()
          .attachShadow({mode: 'open'})
          .innerHTML = `Content in shadowDOM`;
    }
    
    connectedCallback(){
        console.log(this.getAttribute('test1'));
    }
});
<test-component test1="A Attribute"></test-component>

但是!有个问题

如果你定义 CE 它被用在DOM之后,CE将是中DOM和constructor可以读取它的属性。

你应该永远不要依赖这种行为

一个。您的 CE 用户可以 load/define 在 <head>

乙。您的 CE 用户可以执行 let myCE = document.createElement("test-component")
其中 运行 是 constructor,但是 connectedCallback 只会 运行 在 .appendchild(myCE) 执行

的那一刻