2

I wrote a script for binding the "smooth scroll" clicking on a button using the JavaScript Module Pattern.

Since is the first time I write code on module pattern, I need some help on the use of "this".

When I bind the "scroll" function to my "bindevents" function, I get an error saying that the "this", in the "scroll" function, is undefined.

How should i use "this" to select the button I click?

Here is the code:

var s, SmoothScroll = {

  Selectors: {
    Link: $('a[href*="#"]:not([href="#"])')
  },

  scroll: function() {
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname && $(".classes .section").has(this).length == 0 ) {
      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
      if (target.length) {
        $('html, body').animate({
          scrollTop: target.offset().top
        }, 1000);
        return false;
      }
    }
  },

  bindEvents: function() { 
    s.Link.click(function() {
      SmoothScroll.scroll();
    });
  },

  init: function(){
    s = this.Selectors;
    this.bindEvents();
  }

};

SmoothScroll.init();

1 Answer 1

2

Change:

s.Link.click(function() {
  SmoothScroll.scroll();
});

To

s.Link.click(SmoothScroll.scroll);

Now this inside the scroll function will be the element


If the different contexts of this are confusing , you could pass the element as an argument of scroll instead

 bindEvents: function() {
   s.Link.click(function() {
     // "this" is element determined by jQuery 
     SmoothScroll.scroll(this);
   });
 },
 scroll: function(link) {
    // this === SmoothScroll
    if (location.pathname.replace(/^\//,'') == link.pathname.replace(/^\//,'') && location.hostname == link.hostname && $(".classes .section").has(link).length == 0 ) {
      var target = $(link.hash);
  .....  
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks a lot!! Now it works. I just have a question.. why in this case I use scroll without (), but inside the init function I use bindevents() with the ()?
because you are passing the function as reference as opposed to passing an anonymous function that would get this as context for element
And what if I need to bind more functions inside bindEvents?
depends what you need to do. If they are event listeners would do same thing as click
@Matteo Then you should use Function.prototype.call! Or pass the element as a parameter!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.