1

I'm trying to make my page slides scroll when I click on a link in Javascript / jQuery, but I can't figure out how to pass the current increment value of my for loop as a parameter, in a for that binds click events on my links. When I click, it calls my defined function, but with the current value of my i, and not the value it has when the function was defined... Here's some of my code :

temp[0] = 0;
for(var i = 1; i < 8; i++) {
  temp[i] = defaultPositions["slide" + i].top;
  console.log(defaultPositions["slide" + i].top);
  $('a.slide' + i).bind('click', function() {
    $('html, body').animate({scrollTop:(defaultPositions['slide' + i].top / slidesScrollSpeed)}, 1000, function() {
      parallaxScroll();
    });
    return false;
  });
}

How can I pass the i value so that when I click on a link, each link has the expected value instead of all being slide8?

0

1 Answer 1

4

Summary:

for (var i=1;i<8;++i){
  (function(i){
    // Your code using `i` in callbacks here
  })(i);
}

Your problem is that there is a single variable i being shared amongst all your closures (the anonymous functions created for the click handlers, that all "close over" the value of i declared outside the function), and so when the value of that variable is incremented in the loop all the functions are still referencing the same updated value.

By wrapping the body of your loop in a function that gets passed in a value of i, you get a new, distinct variable i with each iteration for your functions to close over. To make it more clear what is going on, you could alternatively write this as:

for (var i=1;i<8;++i){
  (function(slideNum){
    // Your code using `slideNum` in callbacks here
  })(i);
}

Alternatively, you could create a custom variable just for the closure, like so:

for (var i=1;i<8;i++){
  var slideNum = 'slide'+i; // Create a new variable to use in the closure
  temp[i] = defaultPositions[slideNum].top;
  $('a.slide'+i).bind('click', function() {
    $('html, body').animate({
      scrollTop:(defaultPositions[slideNum].top/slidesScrollSpeed)
    }, 1000, function() { parallaxScroll(); });
    return false;
  });
}

Also, note that—depending on the implementation of parallaxScroll()—you could probably simplify that line as just:

$('html, body').animate({
  scrollTop:(defaultPositions[slideNum].top/slidesScrollSpeed)
}, 1000, parallaxScroll );
Sign up to request clarification or add additional context in comments.

2 Comments

That was a perfect answer! Not only did it work, but now I understand what was not working and why. Thank you very much!
@sam_1421 Glad to have helped :)

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.