0

I'm writing a short class (first time using class in Javascript) for handling a menu icon for my site. this menu icon need to be able to be instancied multiple time on the same page.

I have an issue when using scroll event fired function that seems to not be affected to the right class instance, here is my pseudo code:

var DynMenu = function(Name) {
 this.Name = Name;

 this.scrollHandler = function() {
     alert("Scroll: "+this.Name);
 };

 DynMenu.prototype.Pause = function() {
     alert("Pausing menu: "+this.Name);
     $(window).off("scroll", this.scrollHandler);
 };

 DynMenu.prototype.Start = function() {
     alert("Starting menu: "+this.Name);
     $(window).scroll(this.scrollHandler);
 };
}

this code is invoked and used with the following:

var RevendMenu = new DynMenu("MenuIcon1");
RevendMenu.Start();
RevendMenu.Pause();

When Scrolling the page (after calling RevendMenu.Start() but before calling RevendMenu.Pause()), I get the message "Scroll: undefined"

May you tell me why I don't get the value of this.Name and how I can fix this?

Thanks a lot Regards Florent

ehretf
  • 163
  • 10

1 Answers1

1

Event handlers in the browser either set this to the element that triggered that event or, in cases where there is no element that triggers the event, the global object. In browsers the global object is window.

In order to bind this to the object the method belongs to you can use .bind():

$(window).off("scroll", this.scrollHandler.bind(this));

Or, in older browsers that don't have .bind() you can capture this in a closure:

var that = this;
$(window).off("scroll", function() {that.scrollHandler()});

For a more detailed explanation of how this works, see this: How does the "this" keyword in Javascript act within an object literal?

Community
  • 1
  • 1
slebetman
  • 109,858
  • 19
  • 140
  • 171
  • Great thanks Slebetman a lot for your help and the link which is very interesting – ehretf May 10 '15 at 22:13
  • I confirm this is working great to retrieve my object variable but the off doesn't work anymore and I didn't understand why so far, any idea ? – ehretf May 10 '15 at 22:35
  • @ehretf: I don't use jQuery much so you have to read the documentation for the `.off()` method. As for the reason for why the `this` didn't work before, check out the link I referenced at the bottom of my answer. – slebetman May 11 '15 at 01:41
  • Thnaks for your reply, I have checked your post and it is very instructive and well explained. I tried some changes but I didn't find a way to remove the scroll when invoking DynMenu.Pause() while using bind. Replacing `.off()` with `window.removeEventListener("scroll", this.scrollHandler.bind(this), false);` and `.on()` with `window.addEventListener("scroll", this.scrollHandler.bind(this), false);` is the same – ehretf May 11 '15 at 13:36
  • Ah. OK. I understand what `.off()` does now. To remove the event listener you must pass it the same function. All the solutions I showed you creates a new function. Therefore the function passed to `.off()` doesn't match any of the functions passed to `.on()`. To solve this, create just one function by doing `var myHandler = this.scrollHandler.bind(this)` then pass that variable to both `on` and `off` so that `off` may find the function passed to `on` in order to remove it from the event – slebetman May 11 '15 at 14:47
  • Thnaks a lot slebetman, I came to the same conclusion and I confirm this is working perfectly. Thanks a lot for your help and all your feedbacks and explanations – ehretf May 12 '15 at 09:56