zee
zee

Reputation: 359

jQuery's each loop

I'm stuck with understanding a behaviour of my each loop.

Here's my code:

$.each(thumbs, function() {    // where thumbs is array of strings
    project = this;

    $('#gallery').append(
        '<li>'
      + '<a href="/portfolio/' + project + '">'
      + '<img src="/img/' + project + '_bw.jpg" id="' + project + '_bw" />'
      + '<img src="/img/' + project + '_tn.jpg" id="' + project + '_tn" />'
      + '</a>'
      + '</li>'
    );

    // alert(project); - alerts every element of array as expected

    $('#' + project + '_bw').load(function() {

        // alert(project); - alerts only the last element of array, 
        // but as many times as many elements in array

        $('#' + project + '_bw').fadeIn(150,function(){
            $('#' + project + '_tn').css("opacity", 1);
        });
    });
});

The problem is, that when I'm trying to define id of the element, where I want to execute .load function it attaches this function only to the last element of array which I'm looping through.

Upvotes: 0

Views: 592

Answers (1)

3dgoo
3dgoo

Reputation: 15794

Your problem is the scope of project is defined outside of your each loop.

So all the thumbs are looped through, and the load listeners are set. But by the time the first load event is called and the load listener function is called, the project variable is set to the last value of the loop.

So what you need to do is set a local variable inside the each loop to set the variable for each iteration.

Try this:

Javascript

$.each(thumbs, function () {
    var thisProject = this;

    $('#gallery').append(
        '<li>' + '<a href="/portfolio/' + thisProject + '"><img src="/img/' + thisProject + '_bw.jpg" id="' + thisProject + '_bw" /><img src="/img/' + thisProject + '_tn.jpg" id="' + thisProject + '_tn" /></a></li>');

    $('#' + thisProject + '_bw').load(function () {
        $('#' + thisProject + '_bw').fadeIn(150, function () {
            $('#' + thisProject + '_tn').css("opacity", 1);
        });
    });
});

Here is an example of the problem:

HTML

<div id="output"></div>

Javascript

var count = 0;
$.each([500,1000,1500,2000,2500], function() {
    var thisValue = this;
    var inScopeCount = count + 1;
    setTimeout(function() {
        $('#output').append('<strong>For ' + thisValue + ':</strong><br />count: ' + count + '<br /> inScopeCount: ' + inScopeCount + '<br />');
    }, this);
    count += 1;
});

Demo

Upvotes: 1

Related Questions