自定义元素构造函数中的属性缺少依赖于脚本标记位置
Attributes in custom element constructor missing dependent on script tag location
我尝试让 html 自定义元素起作用:
在浏览器中查看以下示例时,我必须得出结论,constructor()
中的 this.dataset.text
属性是:
- 出现在定义自定义元素的脚本之前
- 定义自定义元素的脚本后为空
<html>
<head>
<title>myimage</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div>
before custom element definition: <my-element data-text="Replaced and works as expected">Not Replaced</my-element>
</div>
<script>
class MyElement extends HTMLElement {
constructor() {
super();
this.text_attribute= this.dataset.text;
}
connectedCallback() {
if (this.text_attribute) {
this.innerText = this.text_attribute;
}
}
}
customElements.define('my-element', MyElement);
</script>
<div>
after custom element definition: <my-element data-text="Replaced">Not Replaced</my-element>
</div>
</body>
</html>
这似乎是 chrome 和 Firefox 中的常见行为。我可以提供更多事实:
this.dataset.text
始终存在于 connectedCallback()
- 通过
this.getAttribute('data-text')
访问 text
-属性的行为与上述相同
任何人都可以解释这种看似有问题的行为的目的吗?
这不是错误行为。
您的第一个 <my-element>
由 DOM 解析器处理 在您定义它之前 。
因此,当 constructor
执行时,所有属性都是已知的(在 DOM 中)。
通常您不会在 constructor
中访问 DOM;因为当你这样做时它也会 运行s:
let foo = document.createElement("my-element"); // absolutly no DOM created
这是一个简化的例子:
<style>
my-element { display:block }
</style>
<my-element id="FOO"> ONE </my-element>
<script>
customElements.define('my-element', class extends HTMLElement {
constructor() {
super();
document.body.append(` ► constructor id:${this.id} ◄ `);
}
connectedCallback() {
document.body.append(` ► connected id:${this.id} ◄ `);
}
});
</script>
<my-element id="BAR"> TWO </my-element>
<my-element id="BAZ"> THREE </my-element>
注意
如何将 FOO
innerHTML 写入(因为它已被解析)到 DOM before 它的 constructor
运行s
BAR
和BAZ
构造函数运行如何在之前将其innerHTML
写入DOM
和 id
值还不存在
我看过很多课程,他们通过执行 <script>
async 来“拯救”你免受这种标准行为的影响,毕竟 DOM 被解析。他们不懂技术...
我尝试让 html 自定义元素起作用:
在浏览器中查看以下示例时,我必须得出结论,constructor()
中的 this.dataset.text
属性是:
- 出现在定义自定义元素的脚本之前
- 定义自定义元素的脚本后为空
<html>
<head>
<title>myimage</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div>
before custom element definition: <my-element data-text="Replaced and works as expected">Not Replaced</my-element>
</div>
<script>
class MyElement extends HTMLElement {
constructor() {
super();
this.text_attribute= this.dataset.text;
}
connectedCallback() {
if (this.text_attribute) {
this.innerText = this.text_attribute;
}
}
}
customElements.define('my-element', MyElement);
</script>
<div>
after custom element definition: <my-element data-text="Replaced">Not Replaced</my-element>
</div>
</body>
</html>
这似乎是 chrome 和 Firefox 中的常见行为。我可以提供更多事实:
this.dataset.text
始终存在于connectedCallback()
- 通过
this.getAttribute('data-text')
访问text
-属性的行为与上述相同
任何人都可以解释这种看似有问题的行为的目的吗?
这不是错误行为。
您的第一个 <my-element>
由 DOM 解析器处理 在您定义它之前 。
因此,当 constructor
执行时,所有属性都是已知的(在 DOM 中)。
通常您不会在 constructor
中访问 DOM;因为当你这样做时它也会 运行s:
let foo = document.createElement("my-element"); // absolutly no DOM created
这是一个简化的例子:
<style>
my-element { display:block }
</style>
<my-element id="FOO"> ONE </my-element>
<script>
customElements.define('my-element', class extends HTMLElement {
constructor() {
super();
document.body.append(` ► constructor id:${this.id} ◄ `);
}
connectedCallback() {
document.body.append(` ► connected id:${this.id} ◄ `);
}
});
</script>
<my-element id="BAR"> TWO </my-element>
<my-element id="BAZ"> THREE </my-element>
注意
如何将
FOO
innerHTML 写入(因为它已被解析)到 DOM before 它的constructor
运行sBAR
和BAZ
构造函数运行如何在之前将其innerHTML
写入DOM
和id
值还不存在我看过很多课程,他们通过执行
<script>
async 来“拯救”你免受这种标准行为的影响,毕竟 DOM 被解析。他们不懂技术...