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" 个警报,然后是前一个。