捕获了Javascript事件,但未执行回调函数

时间:2019-03-22 18:54:24

标签: javascript callback lifecycle dom-events

两个类监听一个事件。当ClassA收到事件时,它将从DOM中删除ClassB并在其之后再次添加它。通过(dis)connectedCallback函数添加和删除ClassB的事件处理程序。

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显示引用仍然存在

2 个答案:

答案 0 :(得分:1)

this.testEL未被调用,因为您已经删除了disconnectedCallback中的事件监听器,而另一个箭头函数监听器却因为从未被删除而被调用。

引发事件时,调用

removeAddremoveAdd删除元素并再次添加,元素的删除导致调用disconnectedCallbackthis.testEL侦听器消失之后,添加操作再次导致connectedCallback被调用,该寄存器将注册处理程序,但对于当前事件传播,这些处理程序将不会执行。

示例:

function eventHandler() {
    alert("Hello");
    document.addEventListener('click', () => window.alert("Not happening")) 
}
document.addEventListener('click', eventHandler)

第一次单击文档将仅显示一个警报(“ Hello”)。下次单击将显示两个警报,在此之后,所有单击将是“未发生”警报的一个,然后是上一个警报。

答案 1 :(得分:0)

箭头功能没有自己的“此”

因此,您需要执行以下操作:

var strength = document.getElementById('getstren');
strength.innerHTML = Math.floor((Math.random() * 17) + 1);
document.getElementById('ath').innerHTML = Math.floor(parseInt(strength) / 2) - 5;

或者只是使用常规功能。