Dan*_*man 10 callback class-method web-component custom-element
2023 年 3 月更新
注意:这是有效的,因为在下一个刻度中,lightDOM 中的N 个(不是全部!)DOM 元素将被解析。
对于 (app.) N > 1000你会遇到麻烦,因为延迟将在解析所有 N 个元素之前结束。
因此,要么添加(大约 20 行)代码来实际检查所有 lightDOM 是否已解析。(但是由于您的 DOM 正在遭受 Obesitas 的困扰,因此您可能还会遇到其他性能问题)
或者只是保持 lightDOM中N 个 DOM 元素的数量较小。
当然,您稍后在解析之后添加的任何 DOM都不会影响任何内容(当不触发时)connectedCallback
2021 年 3 月更新:
FireFox 错误已修复,现在的行为与 Chromium 和 Safari 相同。
这意味着等待 JS EventLoop 为空(带有setTimeout或requestAnimationFrame)现在connectedCallback是一个跨浏览器方法
connectedCallback(){
setTimeout(()=>{
// can access lightDOM here
}); // ,0 not required
}
Run Code Online (Sandbox Code Playgroud)
事件循环到底是什么?- 菲利普·罗伯茨
https://www.youtube.com/watch?v=8aGhZQkoFbQ
2020 年 10 月 28 日更新:
现在 Mozilla 工程师 Anne van Kesteren 报告称 FireFox 中存在一个错误:
FireFox 调用connectedCallback 太晚了:
https://bugzilla.mozilla.org/show_bug.cgi?id =1673811
五月第一篇文章。2020年:
在使用 FireFox 一周后,再次遇到 Chrome Element 升级问题。
在交付给 Chromium 浏览器之前忘记将代码包装在 setTimeout 中。
FireFox 打印:ABCD
铬印:ADCD
问题:为什么有区别?
connectedCallback(){
setTimeout(()=>{
// can access lightDOM here
}); // ,0 not required
}
Run Code Online (Sandbox Code Playgroud)
历年相关回答:
注意:Chromium Blink 引擎是 Apples (WebKit)WebCore代码的一个分支!
通过 Supersharps 参考,我们找到了相关线程:
(2016)文档解析器创建自定义元素时的connectedCallback计时
https://github.com/w3c/webcomponents/issues/551
(2019)当子项更改或解析器完成解析子项时需要回调
https://github.com/w3c/webcomponents/issues/809
来源: https: //jsfiddle.net/WebComponents/9p5qyk1z/

我认为 Chrome/Safari 的行为对于初学者来说不太直观,但对于一些更复杂的场景(例如子自定义元素),它会更加一致。
请参阅下面的不同示例。他们在 Firefox 中表现得很奇怪......
另一个我没有勇气编写代码的用例:当解析文档时,也许你还没有得到文档的结尾。因此,当创建自定义元素时,在获得结束标记(永远不会到达)之前,您无法确定获得其所有子元素。
根据 WebKit 的 Ryosuke Niwa 的说法:
那么问题是,在解析所有子元素之前,该元素不会获得connectedCallback。例如,如果整个文档是单个自定义元素,则即使该元素确实位于文档中,该自定义元素也永远不会收到connectedCallback,直到整个文档被获取并解析为止。那会很糟糕。
因此,最好不要在创建自定义元素后立即等待并连接它,这意味着没有子元素。
<script>
customElements.define( 'c-e', class extends HTMLElement {} )
customElements.define('my-element', class extends HTMLElement {
connectedCallback() {
console.log(this.innerHTML, this.childNodes.length)
let span = document.createElement( 'span' )
if (this.innerHTML.indexOf( 'A' ) >= 0 )
span.textContent = 'B'
else
span.textContent = 'D'
setTimeout( () => this.appendChild( span ) )
}
})
</script>
<my-element>A</my-element><my-element>C</my-element>
<br>
<my-element><c-e></c-e>A</my-element><my-element>A<c-e></c-e></my-element>
<br>
<my-element><c-e2></c-e2>A</my-element><my-element>A<c-e2></c-e2></my-element>Run Code Online (Sandbox Code Playgroud)
据我了解,对此达成了共识,导致以(Chrome/Safari)方式调整规范:
通过确保插入到 DOM 中立即触发connectedCallback,而不是将回调反应放在备份元素队列上并让它在下一个微任务检查点触发,修复了w3c/webcomponents#551 。这意味着connectedCallback通常会在元素有零个子元素时被调用,正如预期的那样,而不是根据何时看到下一个自定义元素的随机数。
connectedCallback我们可以得出结论,Firefox 也遵循该规范...是的,但由于上述原因,我们不应该依赖 中的内容。
| 归档时间: |
|
| 查看次数: |
1245 次 |
| 最近记录: |