web组件-在slotchange上自定义事件



谁能解释一下这里发生了什么?我错过什么了吗?

#handleClick() {
this.dispatchEvent(new Event('onClicked'));
}
mySlot.addEventListener('slotchange', () => {
mySlot.addEventListener('click', this.#handleClick); // doesn't work
mySlot.addEventListener('click', () => this.#handleClick()); // works
});
...
myCustomElement.addEventListener('onClicked', (e) => {
console.log(e, e.detail);
});
#handleClick() {
this.dispatchEvent(new Event('onClicked', {bubbles: true, composed: true}));
}
mySlot.addEventListener('slotchange', () => {
mySlot.addEventListener('click', this.#handleClick); // works
});
...
...
myCustomElement.addEventListener('onClicked', (e) => {
console.log(e, e.detail);
});

我知道自定义事件没有达到"light-DOM"这就是为什么我能理解为什么我们应该把"组成:真"one_answers"泡沫:真"放在一起。但是我为什么要这么做呢?addEventListener('click', () =>this.#handleClick())无需使事件"可组合"就可以工作。

下面是一个更好地理解问题的方法:https://jsfiddle.net/rv6w3xj1/1/

您的问题是scope

A Functionreference获得与箭头函数定义不同的this作用域,
因此,您的this.dispatchEvent在不同的DOM元素上/从不同的DOM元素执行。

当该元素在shadowDOM内时,需要bubbles:true;composed:true通过shadowRoot

进行

转义我将您的代码修剪到最低限度,slotslotchange这个无关。

<custom-element><h2>Click SLOT</h2></custom-element>
<script>
customElements.define('custom-element', class extends HTMLElement {
constructor() {
super().attachShadow({ mode: "open" })
.innerHTML = `<h1>Click H1</h1><slot></slot>`;
const addClick = (name) => {
const el = this.shadowRoot.querySelector(name);
el.addEventListener('click',        this.#handleClick    ); // func REF
el.addEventListener('click', (e) => this.#handleClick(e) ); // func DEF
}
addClick("h1");
addClick("slot");
}
#handleClick(e) {
console.error(e.type, 'handleClick scope:', this);
this.dispatchEvent(new CustomEvent('onClicked', {
bubbles: true, composed: true,
}));
}
});
document.querySelector('custom-element').addEventListener('onClicked', (e) => {
console.log("target:", e.target, e.target.getRootNode(), 
"ncomposedPath[0]:", e.composedPath()[0]);
});
</script>

你可以用oldskoolthis.handleClick.bind(this)
来修复它,但这比(e) => this.handleClick(e)
更容易出错,因为大多数初级开发人员不明白bind

是怎么回事

最新更新