gpt4 book ai didi

javascript - 当所有子自定义元素都已连接时如何获得 'connectedCallback'

转载 作者:技术小花猫 更新时间:2023-10-29 12:34:30 24 4
gpt4 key购买 nike

我正在使用 Web Components v1。

假设有两个自定义元素:

parent-element.html

<template id="parent-element">
<child-element></child-element>
</template>

child-element.html

<template id="child-element">
<!-- some markup here -->
</template>

我正在尝试在 parent-element 中使用 connectedCallback 来初始化整个父/子 DOM 结构,这需要与 中定义的方法进行交互code>子元素.

但是,在为 customElement 触发 connectedCallback 时,似乎没有正确定义 child-element:

parent-element.js

class parent_element extends HTMLElement {
connectedCallback() {
//shadow root created from template in constructor previously
var el = this.shadow_root.querySelector("child-element");
el.my_method();
}
}

这是行不通的,因为 el 是一个 HTMLElement 而不是预期的 child-element

一旦其模板中的所有子自定义元素都已正确附加,我需要为 parent-element 回调。

this question 中的解决方案似乎不起作用; this.parentElementchild-element connectedCallback() 中为 null

电影

最佳答案

在 ShadowDOM 模板中使用插槽元素。

以某种方式构建您的自定义元素,以便它们可以存在于任何上下文中,例如作为子元素或父元素,而不与其他自定义元素有任何依赖关系。这种方法将为您提供一个模块化设计,您可以在任何情况下使用您的自定义元素。

但您仍然想在子元素出现时做一些事情,例如选择它们或调用子元素的方法。

插槽元素

为了解决这个问题 <slot> 元素被引入。使用插槽元素,您可以在 ShadowDOM 模板中创建占位符。只需将一个元素作为 DOM 中的子项放置在您的自定义元素 中,即可使用这些占位符。然后子元素将被放置在 <slot> 所在的位置。放置元素。

但是你怎么知道占位符是否已经被元素填充了呢?

槽元素可以监听一个名为 slotchange 的独特事件.只要将一个元素(或多个元素)放置在 slot 的位置上,就会触发此事件。元素。

在事件的监听器中,您可以使用 HTMLSlotElement.assignedNodes() 访问占位符中的所有元素。或 HTMLSlotElement.assignedElements() 方法。这些返回一个数组,其中的元素放置在 slot 中.

现在您可以等待 children 被放置在插槽中,并对存在的 children 做一些事情。

这种方式允许您只操作 DOM 而让 ShadowDOM 单独工作,让它完成它的工作。就像您处理常规 HTML 元素一样。

事件是否会等待所有子元素连接完成?

是的,slotchange毕竟事件被触发connectedCallback已调用自定义元素的方法。这意味着在收听赛事时没有比赛条件或缺少设置。

class ParentElement extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
this.shadowRoot.innerHTML = `
<h2>Parent Element</h2>
<slot></slot>
`;
console.log("I'm a parent and have slots.");

// Select the slot element from the ShadowDOM..
const slot = this.shadowRoot.querySelector('slot');

// ..and listen for the slotchange event.
slot.addEventListener('slotchange', (event) => {
// Get the elements assigned to the slot..
const children = event.target.assignedElements();

// ..loop over them and call their methods.
children.forEach(child => {
if (child.tagName.toLowerCase() === 'child-element') {
child.shout()
}
});
});
}

connectedCallback() {
console.log("I'm a parent and am now connected");
}
}

customElements.define('parent-element', ParentElement);

class ChildElement extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
this.shadowRoot.innerHTML = `
<h3>Child Element</h3>
`;
}

connectedCallback() {
console.log("I'm a child and am now connected.");
}

shout() {
console.log("I'm a child and placed inside a slot.");
}

}

customElements.define('child-element', ChildElement);
<parent-element>
<child-element></child-element>
<child-element></child-element>
<child-element></child-element>
</parent-element>

关于javascript - 当所有子自定义元素都已连接时如何获得 'connectedCallback',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48663678/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com