0

Two classes listening to one Event. When ClassA gets the event it removes ClassB from DOM and adds it right after it again. The event handlers of ClassB get added and removed by the (dis)connectedCallback functions.

ClassB still notices the Event right after it as well but it does not execute the callback function anymore.

I checked the eventhandler of ClassB. It catches the event and it has a reference to its callback function but it is not executing it. When I disable the method removeAdd()of ClassA it works.

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();

This is the output when the method removeAdd() of ClassA is commented out:

constructed
connected
TEST heared () => { this.test(); }
callback <test-class>

This is the output with full code:

constructed
connected
disconnected
connected
TEST heared () => { this.test(); }

But it is not executing this.testEL. Why?

/edit: After further investigations I noticed that the complete event handler broke after getting removed and added again as even additional new 'TEST' events do not fire the callback function, although the console.log shows that the reference is still there.

Andreas
  • 47
  • 10

2 Answers2

1

this.testEL is not getting called because you have removed the event listener in the disconnectedCallback and the other arrow function listener is getting called because it was never removed.

removeAdd is called when the event is raised, removeAdd removes the element and add again, the removal of the element causes disconnectedCallback to be called and the this.testEL listener is gone, the add again causes connectedCallback to be called which register the handlers BUT these handlers will not get executed for the current event propagation.

Example:

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

The first click on document will only show one alert ("Hello"). The next click will show both alerts, after that for all clicks it will be one more of "Not happening" alerts then the previous one.

Ankur
  • 33,367
  • 2
  • 46
  • 72
  • So it means that all event handlers of an event must already be defined when the event gets fired? Event handlers added while the event is already propagating do not get recognized, even if the new event handler is at the end of the propagation chain? – Andreas Mar 23 '19 at 08:48
  • The newly added handler will be called in the next event. – Ankur Mar 23 '19 at 08:51
0

Arrow functions do not have their own "this"

So, you need either do something like this:

window.addEventListener('TEST', this.testEL.bind(this));

Or just use regular function.

Code4Art
  • 741
  • 8
  • 9
  • I can't use that as it returns an anonymous function and makes the eventlistener unremovable. I tried ´this.test´ as callback function but that doesn't work either. The callback functions never gets executed. It has something to do with the ´removeAdd´ method of classA. – Andreas Mar 23 '19 at 08:11