0

I've got a class that assigns an eventListener to an html element when its loaded. When that html element is clicked, it invokes a function from that same class like so:

class LiveViewController extends ViewController{

viewLoads(){
    $("#mydiv")[0].addEventListener("click",this.someFunction);
}

someFunction(){
    console.log(this);
}

}

The issue is that i would like to somehow have a reference of the instance of the class in someFunction but "this" refers to the element itself. What would be your suggested way of doing this?

Return-1
  • 1,953
  • 1
  • 12
  • 44
  • Possible duplicate of [How does the "this" keyword work?](https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – jonrsharpe Oct 29 '17 at 11:28

2 Answers2

1

When you specify a function to be used as an event handler in jQuery, that function gets access to the raw DOM element that initiated the event as this. So the classical solution would be to closure the class context inside the handler as self:

class LiveViewController extends ViewController{

  viewLoads(){
    var self = this;
    $("#mydiv")[0].addEventListener("click", function() {
      self.someFunction(self);
    });
  }
  someFunction(context){
    console.log(context);
  }
}

You even don't need to pass the context at all:

class LiveViewController extends ViewController{

  viewLoads(){
    var self = this;
    $("#mydiv")[0].addEventListener("click", function() {
      self.someFunction();
    });
  }
  someFunction(){
    console.log(this);
  }
}

At last you may use .bind to bind appropriate context:

class LiveViewController{
  viewLoads(){
    $("#mydiv")[0].addEventListener("click", this.someFunction.bind(this));
  }
  someFunction(){
    console.log(this);
  }
}

To get an access to both of instantiated object and dom element you may use

class LiveViewController extends ViewController{

  viewLoads(){
    var self = this;
    $("#mydiv")[0].addEventListener("click", function() {
      self.someFunction(this);
    });
  }
  someFunction(element){
    console.log(this);
    console.log(element);
  }
}
dhilt
  • 13,532
  • 6
  • 48
  • 67
  • Why cant i +5 this? – Return-1 Oct 29 '17 at 11:33
  • @GeorgeAvgoustis You also may "accept" this answer. – dhilt Oct 29 '17 at 11:34
  • I will, just waiting for the time limit. Not to stretch it but.. how would i go about if i wanted to have access BOTH to the class AND the element? – Return-1 Oct 29 '17 at 11:35
  • Ok thats a good way. Is it too stupid to do : $("#rollDieDiv")[0].addEventListener("click",this.rollDiePressed.bind({"element":$("#rollDieDiv")[0],"classInstance":this})); ? – Return-1 Oct 29 '17 at 11:38
0

You can try this:

 class LiveViewController extends ViewController {

     viewLoads(){
         // You can pass data to the callback directly as event.data in jQuery
         $("#mydiv").on('click', {self: this}, this.someFunction);  

         // or Another way would be to use bind
         // $("#mydiv").click(this.someFunction.bind($, this));
         // someFunction(self, event) - definition
     }

     someFunction(event){
        console.log(event.data.self);
     }
  }
Arjun Kariyadan
  • 454
  • 2
  • 11