有人能解释一下这里发生了什么吗?我错过了什么吗?
#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",这就是为什么我可以理解为什么我们应该将"composed:真实和气泡:但是为什么mySlot. addEventListener('click ',()=〉this.#handleClick())可以在不需要将事件设置为"可组合"的情况下工作呢?
为了更好地理解这个问题,下面是一个小提琴:https://jsfiddle.net/rv6w3xj1/1/
1条答案
按热度按时间hmmo2u0o1#
您的问题是范围***
函数引用获得的
this
作用域与箭头函数定义不同,因此
this.dispatchEvent
是在不同的DOM元素上执行的。当该元素位于shadowDOM中时,它需要
bubbles:true;composed:true
来通过shadowRoot进行 * 转义我将您的代码精简到最低限度,
slot
和slotchange
与此***无关您可以使用 oldskool
this.handleClick.bind(this)
进行修复,但这比
(e) => this.handleClick(e)
更容易出错因为大多数初级开发人员不了解
bind
的工作原理