Web Components自定义parsedCallback方法失效,innerHTML仍未解析
Web Components 自定义
parsedCallback 不生效问题 重要提示
**重要提示:**几乎所有IDE都会自动延迟JavaScript执行,这意味着你可能无法在IDE中复现该问题
问题场景
当使用Web Components API时,若定义组件的脚本在文档HTML解析前执行,会出现一个问题:原生connectedCallback生命周期方法执行时,元素的innerHTML尚未解析。这是因为该方法在自定义元素的开始标签执行,而其子元素的解析尚未开始。
示例代码:
<script> customElements.define('my-element', MYElement); </script> <my-element> <span>Content</span> </my-element>
尝试的解决方案
为解决此问题,我尝试实现自定义parsedCallback方法,但目前未生效。
核心思路:浏览器会同步解析HTML,因此当检测到“更晚的”兄弟元素被解析时,即可确定组件内部所有内容已解析完成。
具体实现细节:
- 给组件的父元素添加
MutationObserver,监听新增的非当前组件的子节点。 - 为避免标记中无“自然”兄弟元素的情况,在组件后添加一个注释节点确保方案始终有效。
实现代码:
class MYElement extends HTMLElement { static counter = 0; constructor() { super(); this._id = MYElement.counter++; } connectedCallback() { console.log(`${this._id} connected`); console.log(`${this._id} has innerHTML on connected = ${this.innerHTML !== ""}`); const parent = this.parentElement; const marker = document.createComment(this._id); const observer = new MutationObserver((mutations) => { mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node !== this) { console.log(`${this._id} younger sibling detected`); this.parsedCallback(); marker.remove(); observer.disconnect(); } }); }); }); observer.observe(parent, { childList: true }); parent.appendChild(marker); } parsedCallback() { console.log(`${this._id} parsed`); console.log(`${this._id} has innerHTML on parsed = ${this.innerHTML !== ""}`); } }
预期与实际输出
预期输出:
0 connected 0 has innerHTML on connected = false 0 younger sibling detected 0 parsed 0 has innerHTML on parsed = true
实际输出(最后一行不符合预期):
0 has innerHTML on parsed = false
内容的提问来源于stack exchange,提问作者Oscar
相关产品推荐
相关产品推荐

