con*_*exo 6 javascript addeventlistener ecmascript-6 custom-element removeeventlistener
如何删除我window在 constructor 下面绑定的点击侦听器?我需要它来监听window,我需要访问它里面的按钮实例。
class MyEl extends HTMLButtonElement {
constructor() {
super();
this.clickCount = 0;
window.addEventListener('click', this.clickHandler.bind(this));
}
clickHandler(e) {
if (e.target === this) {
this.textContent = `clicked ${++this.clickCount} times`;
window.removeEventListener('click', this.clickHandler);
}
}
disconnectedCallback() {
window.removeEventListener('click', this.clickHandler);
}
}
customElements.define('my-el', MyEl, { extends: 'button' });Run Code Online (Sandbox Code Playgroud)
<button is="my-el" type="button">Click me</button>Run Code Online (Sandbox Code Playgroud)
您当前的实现是不可能的 - 每次调用.bind都会创建一个新的单独函数,并且removeEventListener如果传递的函数与传递给的函数相同 ( ===),则您只能调用删除侦听器addEventListener(就像.includes数组或.has集合一样) :
const fn = () => 'foo';
console.log(fn.bind(window) === fn.bind(window));Run Code Online (Sandbox Code Playgroud)
作为一种解决方法,您可以将绑定函数分配给实例的属性:
class MyEl extends HTMLButtonElement {
constructor() {
super();
this.clickCount = 0;
this.boundListener = this.clickHandler.bind(this);
window.addEventListener('click', this.boundListener);
}
clickHandler(e) {
this.textContent = `clicked ${++this.clickCount} times`;
window.removeEventListener('click', this.boundListener);
}
}
customElements.define('my-el', MyEl, { extends: 'button' });Run Code Online (Sandbox Code Playgroud)
<button is="my-el" type="button">Click me</button>Run Code Online (Sandbox Code Playgroud)
另一种模式是将你的监听器放在里面在构造函数
要删除事件监听器(无论什么模式),您可以添加“删除”功能在创建事件监听器时
由于remove函数是在listen作用域内调用的,所以它使用相同的name和function
伪代码:
listen(name , func){
window.addEventListener(name, func);
return () => window.removeEventListener( name , func );
}
let remove = listen( 'click' , () => alert('BOO!') );
//cleanup:
remove();
Run Code Online (Sandbox Code Playgroud)
运行代码片段以查看它与多个按钮一起使用
一旦您对事件进行更多操作,即可节省您一个小时...
请注意,如果您希望 WebComponents(即具有ShadowDOM 的 CustomElements)需要带有该composed:true属性的 CustomEvents,则它们会冒泡超过其 ShadowDOM 边界
new CustomEvent("check", {
bubbles: true,
//cancelable: false,
composed: true // required to break out of shadowDOM
});
Run Code Online (Sandbox Code Playgroud)
注意:这个例子不能在 Safari 上运行,因为 Apple 拒绝实现扩展元素:extends HTMLButtonElement
listen(name , func){
window.addEventListener(name, func);
return () => window.removeEventListener( name , func );
}
let remove = listen( 'click' , () => alert('BOO!') );
//cleanup:
remove();
Run Code Online (Sandbox Code Playgroud)
new CustomEvent("check", {
bubbles: true,
//cancelable: false,
composed: true // required to break out of shadowDOM
});
Run Code Online (Sandbox Code Playgroud)
class MyEl extends HTMLButtonElement {
constructor() {
let ME = super();// super() retuns this scope; ME makes code easier to read
let count = 0;// you do not have to stick everything on the Element
ME.mute = ME.listen('click' , event => {
//this function is in constructor scope, so has access to ALL its contents
if(event.target === ME) //because ALL click events will fire!
ME.textContent = `clicked ${ME.id} ${++count} times`;
//if you only want to allow N clicks per button you call ME.mute() here
});
}
listen(name , func){
window.addEventListener( name , func );
console.log('added' , name , this.id );
return () => { // return a Function!
console.log( 'removeEventListener' , name , 'from' , this.id);
this.style.opacity=.5;
window.removeEventListener( name , func );
}
}
eol(){ // End of Life
this.parentNode.removeChild(this);
}
disconnectedCallback() {
console.log('disconnectedCallback');
this.mute();
}
}
customElements.define('my-el', MyEl, { extends: 'button' });Run Code Online (Sandbox Code Playgroud)
笔记:
count不可用,this.count但可用于构造函数范围内定义的所有函数。所以它是(有点)私有的,只有点击功能可以更新它。
onclick=Two.disconnectedCallback()就像这个例子一样,该函数不会删除该元素。
另请参阅:https://pm.dartus.fr/blog/a-complete-guide-on-shadow-dom-and-event-propagation/
| 归档时间: |
|
| 查看次数: |
2353 次 |
| 最近记录: |