Home > Software design >  Manage clicks events inside Javascript Class?
Manage clicks events inside Javascript Class?

Time:12-17

I am always working with old vanilla javascript (es5) with some functionnalities of ES6, now I am working on something, so I created a class to display my html content, in a web page, then add a click

My class is :

class Field {
    constructor(key, label, status, isUnsubscribed){
        this.key = key;
        this.label = label;
        this.status = status;
        this.isUnsubscribed = isUnsubscribed;
    }

    // want this to be executed on click
    test(){
        alert(this.key);
    }

    returnHTMLField(){

        // Global Container
        let fieldContainer = document.createElement("div");
        
        fieldContainer.addEventListener("click", function(){
            // issue here, this return the element itself, which makes sense
            this.test()
        })

        return fieldContainer;
    }
}

So basically I am creating an object with a method adding the component to the DOM, this is working fine with the help of another class, but now whenever I click I want the test function to be executed, but this inside the eventListener action isn't returning the Object state, it is returning the component ( DOM element ), which is a normal behavior, I don't know how can I execute the test function inside the event listener..

Any help would be much appreciated

CodePudding user response:

try using arrow function

fieldContainer.addEventListener("click", ()=>{ this.test() )

CodePudding user response:

You can use arrow function to bind the this to the parent scope instead of creating a separate lexical scope.

class Field {
    constructor(key, label, status, isUnsubscribed){
        this.key = key;
        this.label = label;
        this.status = status;
        this.isUnsubscribed = isUnsubscribed;
    }

    // want this to be executed on click
    test(){
        alert(this.key);
    }

    returnHTMLField(){

        // Global Container
        let fieldContainer = document.createElement("div");
        
        fieldContainer.addEventListener("click",() => {
            // issue here, this return the element itself, which makes sense
            this.test()
        })

        return fieldContainer;
    }
}

CodePudding user response:

So if you prefer ES5 then just .bind(this) it.

class Field {
    constructor(opts){
        Object.assign(this, opts); // Bonus ES6 code here 
    }

    // want this to be executed on click
    test(){
        alert(this.key);
    }

    returnHTMLField(){

        // Global Container
        let fieldContainer = document.createElement("div");
        
        fieldContainer.addEventListener("click", function(){
            // issue here, this return the element itself, which makes sense
            this.test()
        }.bind(this)) // <--- HERE

        return fieldContainer;
    }
}

var f = new Field({ key           : 10
                  , label         : "Test"
                  , status        : "OK"
                  , isUnsubscribed: false
                  });
                  
console.log(f.returnHTMLField().dispatchEvent(new Event("click")));

  • Related