3

I have something similar to the following but I get the error: "this._toggle is not a function"

function handler(){
  this._toggle();
}
SelectFX.prototype._toggle = function(){
   ...
   this.removeEventListener('click', handler);
}
this.addEventListener('click', handler);

which I'm guessing is to do with the scope that addEventListener creates,

I would of thought then that adding this to a variable would fix but this code:

var self = this;
function handler(){
  self._toggle();
}
SelectFX.prototype._toggle = function(){
   ...
   this.removeEventListener('click', handler);
}
this.addEventListener('click', handler);

But the above gives the error "Cannot read property '_toggle ' of undefined"

If I use an anonymous function like below for the click handler it works fine but I need to Remove the Click Event later on, please help

SelectFX.prototype._toggle = function(){
   ...
}
this.addEventListener('click', function(){
   this._toggle();  //Works fine but I need to remove this addEventListener later on
});

I've create a Gist here with the Full plugin https://gist.github.com/grassed/ce76d9b2a5fa6ab9e5be which centers around this.selPlaceholder.addEventListener( 'click', clickHandler);

grasesed
  • 915
  • 2
  • 9
  • 15
  • I have an idea, but I can't really understand what exactly you're trying to do. What's the goal? – Purag Aug 11 '15 at 07:23
  • 1
    Can you post more complete code, it's unclear `this.addEventListener('click', handler);`, the `this` here is pointing to what. – fuyushimoya Aug 11 '15 at 07:24
  • Ive summarized the issue as the actual plugin is quite large I will try to add it somewhere – grasesed Aug 11 '15 at 07:38
  • 1
    possible duplicate of [Javascript scope addEventListener and this](http://stackoverflow.com/questions/13996263/javascript-scope-addeventlistener-and-this) – Justus Romijn Aug 11 '15 at 07:46
  • @JustusRomijn thats what Ive tried to follow although there isnt an example of not using an anonymous function as the click handler – grasesed Aug 11 '15 at 07:52
  • You can use bind for that, ill give you an example in a sec – Justus Romijn Aug 11 '15 at 09:13
  • Detailled solutions by MDN: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#The_value_of_this_within_the_handler – sp00m Aug 11 '15 at 09:37

1 Answers1

1

You can use the native bind function to pass the object that should represent this in the function called. You can use that also for event listeners. In the example below, I pass in someObject to be this when someListener is being called.

var el = document.getElementById("clickable-span");

var someObject = {
  clickCount: 0,
  someListener: function(){
    this.clickCount++;
    this.showCount();
    el.innerText = 'Click me again';
  },
      
  showCount: function(){
    document.getElementById('target-span').innerText = 'You clicked ' + this.clickCount + ' time(s)';
  }
}

// use bind to pass in what `this` should refer to in the someListener method
// we want `this` to point to someObject so we can use the clickcount and such
el.addEventListener(
  "click", 
  someObject.someListener.bind(someObject)
);
<button id="clickable-span">Click me</button>
<hr />
<span id="target-span"></span>
Justus Romijn
  • 15,699
  • 5
  • 51
  • 63