Javascript 事件已捕获,但回调函数未执行
Javascript event catched, but callback function not executing
两个 类 听一个事件。当 ClassA 获取事件时,它会从 DOM 中删除 ClassB 并再次将其添加到它之后。 ClassB 的事件处理程序由 (dis)connectedCallback 函数添加和删除。
ClassB 仍然注意到紧随其后的事件,但它不再执行回调函数。
我检查了ClassB的事件处理程序。它捕获事件并且它有对其回调函数的引用但它没有执行它。当我禁用 ClassA 的 removeAdd()
方法时,它起作用了。
class ClassA {
constructor() {
window.addEventListener('TEST', this.removeAdd);
}
removeAdd() {
document.body.removeChild(testclass);
document.body.appendChild(testclass);
}
}
new ClassA();
class ClassB extends HTMLElement {
constructor() {
super();
console.log("constructed");
var shadow = this.attachShadow({mode:'open'});
shadow.appendChild(document.createElement('TEXTAREA'));
this.testEL = () => { this.test(); };
}
connectedCallback() {
console.log("connected");
window.addEventListener('TEST', () => { console.log('TEST heared', this.testEL.toString()); });
window.addEventListener('TEST', this.testEL);
}
disconnectedCallback() {
console.log("disconnected");
window.removeEventListener('TEST', this.testEL);
}
test() {
console.log('callback', this);
}
}
customElements.define('test-class', ClassB);
var testclass = new ClassB();
document.body.appendChild(testclass);
function fevent() {
var ev = new Event('TEST');
window.dispatchEvent(ev);
}
fevent();
这是ClassA的方法removeAdd()
被注释掉后的输出:
constructed
connected
TEST heared () => { this.test(); }
callback <test-class>
这是完整代码的输出:
constructed
connected
disconnected
connected
TEST heared () => { this.test(); }
但它没有执行this.testEL
。为什么?
/edit:经过进一步调查,我注意到完整的事件处理程序在被删除并再次添加后中断,因为即使是额外的新 'TEST' 事件也不会触发回调函数,尽管 console.log 显示引用仍然存在。
箭头函数没有自己的"this"
因此,您需要执行以下操作:
window.addEventListener('TEST', this.testEL.bind(this));
或者只使用常规函数。
this.testEL
未被调用,因为您已删除 disconnectedCallback
中的事件侦听器,而另一个箭头函数侦听器正在被调用,因为它从未被删除。
removeAdd
在引发事件时调用,removeAdd
删除元素并再次添加,删除元素导致调用 disconnectedCallback
并且 this.testEL
监听器消失了,添加再次导致 connectedCallback
被调用,注册处理程序但是这些处理程序不会为当前事件传播执行。
示例:
function eventHandler() {
alert("Hello");
document.addEventListener('click', () => window.alert("Not happening"))
}
document.addEventListener('click', eventHandler)
第一次点击文档只会显示一个警告 ("Hello")。下一次点击将显示两个警报,此后所有点击都将显示 "Not happening" 个警报,然后是前一个。
两个 类 听一个事件。当 ClassA 获取事件时,它会从 DOM 中删除 ClassB 并再次将其添加到它之后。 ClassB 的事件处理程序由 (dis)connectedCallback 函数添加和删除。
ClassB 仍然注意到紧随其后的事件,但它不再执行回调函数。
我检查了ClassB的事件处理程序。它捕获事件并且它有对其回调函数的引用但它没有执行它。当我禁用 ClassA 的 removeAdd()
方法时,它起作用了。
class ClassA {
constructor() {
window.addEventListener('TEST', this.removeAdd);
}
removeAdd() {
document.body.removeChild(testclass);
document.body.appendChild(testclass);
}
}
new ClassA();
class ClassB extends HTMLElement {
constructor() {
super();
console.log("constructed");
var shadow = this.attachShadow({mode:'open'});
shadow.appendChild(document.createElement('TEXTAREA'));
this.testEL = () => { this.test(); };
}
connectedCallback() {
console.log("connected");
window.addEventListener('TEST', () => { console.log('TEST heared', this.testEL.toString()); });
window.addEventListener('TEST', this.testEL);
}
disconnectedCallback() {
console.log("disconnected");
window.removeEventListener('TEST', this.testEL);
}
test() {
console.log('callback', this);
}
}
customElements.define('test-class', ClassB);
var testclass = new ClassB();
document.body.appendChild(testclass);
function fevent() {
var ev = new Event('TEST');
window.dispatchEvent(ev);
}
fevent();
这是ClassA的方法removeAdd()
被注释掉后的输出:
constructed
connected
TEST heared () => { this.test(); }
callback <test-class>
这是完整代码的输出:
constructed
connected
disconnected
connected
TEST heared () => { this.test(); }
但它没有执行this.testEL
。为什么?
/edit:经过进一步调查,我注意到完整的事件处理程序在被删除并再次添加后中断,因为即使是额外的新 'TEST' 事件也不会触发回调函数,尽管 console.log 显示引用仍然存在。
箭头函数没有自己的"this"
因此,您需要执行以下操作:
window.addEventListener('TEST', this.testEL.bind(this));
或者只使用常规函数。
this.testEL
未被调用,因为您已删除 disconnectedCallback
中的事件侦听器,而另一个箭头函数侦听器正在被调用,因为它从未被删除。
removeAdd
在引发事件时调用,removeAdd
删除元素并再次添加,删除元素导致调用 disconnectedCallback
并且 this.testEL
监听器消失了,添加再次导致 connectedCallback
被调用,注册处理程序但是这些处理程序不会为当前事件传播执行。
示例:
function eventHandler() {
alert("Hello");
document.addEventListener('click', () => window.alert("Not happening"))
}
document.addEventListener('click', eventHandler)
第一次点击文档只会显示一个警告 ("Hello")。下一次点击将显示两个警报,此后所有点击都将显示 "Not happening" 个警报,然后是前一个。