如何在Web组件首次渲染前捕获已添加的子元素?
Web组件生命周期:首次渲染前修改子元素避免闪烁
我正在创建一个Web组件,用于修改其子元素的行为与样式,目标是在首次渲染前完成修改,避免出现页面闪烁问题。
以下是实现点击.trigger类标题隐藏.content类内容的示例组件:
JavaScript 代码
"use strict"; customElements.define( "shrinkable-content", class extends HTMLElement { static observedAttributes = ["shrunk"]; constructor() { super(); } connectedCallback() { setTimeout(() => { const triggers = Array.from(this.getElementsByClassName("trigger")); const contents = Array.from(this.getElementsByClassName("content")); if (typeof this.shrunk === "undefined") { this.shrunk = false; } contents.forEach( (content) => { content.oldStyle = content.style.display; if (this.shrunk) content.style.display = "none"; }); triggers.forEach((trigger) => { trigger.style.cursor = "pointer"; trigger.addEventListener("click", (event) => { this.shrunk = !this.shrunk; contents.forEach((content) => { content.style.display = this.shrunk ? "none" : content.oldStyle; }); }); }); }); } attributeChangedCallback(name, oldValue, newValue) { if (name === 'shrunk') this.shrunk = (newValue === "true") || (newValue === ""); } } );
HTML 代码
<!DOCTYPE html> <html lang="en-US"> <head> <title>HTML + JavaScript</title> <script src="./shrinkable-content.js"></script> </head> <body> <ul> <li> <shrinkable-content shrunk> <button class="trigger">Alpha Item</button> <ul class="content"> <li>Item One</li> <li>Item Two</li> </ul> </shrinkable-content> </li> </ul> </body> </html>
核心矛盾
注意connectedCallback开头的setTimeout()调用:
- 不添加时,函数会在子元素挂载前执行,无法获取到目标子元素;
- 添加后,代码延迟到首次渲染后执行,会导致页面出现闪烁。
补充说明:我极力避免使用Shadow DOM方案,这与我遵循的设计原则相悖。
编辑说明:已有一些针对收缩功能的解决方案,但核心问题聚焦于Web组件的生命周期,示例仅用于辅助讨论该问题。
内容的提问来源于stack exchange,提问作者Paul R Jones
相关产品推荐
相关产品推荐

