Thibault
Thibault

Reputation: 137

jQuery increment trouble

I'm trying to do some jQuery to navigate through sections with an increment class. But my jQuery code looks wrong. In the console there is this message

TypeError: nextSection.offset(...) is undefined

This is my codde :

for(var i = 0; i < 11; i++) {
    $('.project-' + i + '> .arrows > .arrow-bottom').click(function() {
        $('html, body').animate({
            scrollTop: $('.project-' + i+1).offset().top()
        }, 750);
    });

Someone knows why it doesn't work?

Thank you!

Upvotes: 0

Views: 60

Answers (2)

ibrahim mahrir
ibrahim mahrir

Reputation: 31682

All the event listeners will have a reference to the same i which will be incremented each time (untill the point where i becomes the boundary 11). So when the event listeners are called they will acess the value of that reference of i they got which will be 11 for all of them. So scrollTop: $('.project-' + i+1).offset().top() will be scrollTop: $('.project-' + 12).offset().top() for all of the items (which I assume not an element) and thus the offset will be undefined.

You can use an IIFE (Imediately Invoked Function Expression) to create a separate closure for each iteration, thus the event listeners will have unique values like this:

for(var i = 0; i < 11; i++) {
    (function(index) { // index will be created for each iteration (new one every time)
        // instead of i use index
        $('.project-' + index + '> .arrows > .arrow-bottom').click(function() {
            $('html, body').animate({
                scrollTop: $('.project-' + index + 1).offset().top()
            }, 750);
        });
    })(i); // pass i to the call to initialize index of the IIFE
}

Upvotes: 1

Ayman El Temsahi
Ayman El Temsahi

Reputation: 2610

The problem is probably with closure, try changing your code to this:

for (var i = 0; i < 11; i++) {
  (function(j) {
    $('.project-' + j + '> .arrows > .arrow-bottom').click(function() {
      $('html, body').animate({
        scrollTop: $('.project-' + (j + 1)).offset().top()
      }, 750);
    });
  }(i));
}

You can refer to this post for more about closure and how it works, How do JavaScript closures work?

Upvotes: 3

Related Questions