Question

Okay this one's starting to freak me out: I have several div containers within the class "tooltipBox", but with different contents. In my little script, I try to store an array of all those divs in a variable, like so:

var agents = $( ".tooltipBox" );

However, when I want to use that array now, it's undefined. When I test the selector on its own (like simply by alert()-ing it), it does work. What's the problem here?

This is where the selector is used:

    $( "#runSimBtn" ).click(function runSimulation() {
        $( "#lContent h2" ).text("Simulation in progress...");

        var agents = $( "div.tooltipBox" );
        var falloutTimes = $( ".rFO" );

        var i, j = 0;

        for(i = 0, j = 0; i < agents.length, j < falloutTimes.length; i++, j++) {
            var ttl = falloutTimes[j].value;

            if((ttl != undefined) && (ttl != 999)) {
                setTimeout(function() {
                    agents[i].animate({ backgroundColor: "#FF0000" }, 500);
                }, ttl*1000);
            } else {
                continue;
            }
        }
    });

Also tried the selector in the browser-console (Firefox) and also there I can select the div, but as soon as I want to store the selection (even of a single div) into a variable, it returns undefined.

Thanks in advance...

Was it helpful?

Solution

As I pointed out in the comments, it is a problem with using closure variables in a loop.

Try

$("#runSimBtn").click(function runSimulation() {
    $("#lContent h2").text("Simulation in progress...");

    var agents = $("div.tooltipBox");
    var falloutTimes = $(".rFO");

    var i, j = 0;

    for (i = 0, j = 0; i < agents.length, j < falloutTimes.length; i++, j++) {
        var ttl = falloutTimes[j].value;

        if ((ttl != undefined) && (ttl != 999)) {
            (function (i, ttl) {
                setTimeout(function () {
                    agents[i].animate({
                        backgroundColor: "#FF0000"
                    }, 500);
                }, ttl * 1000);
            })(i, ttl);
        } else {
            continue;
        }
    }
});

OTHER TIPS

I think what is going on here is that when the setTimeout calls the function after 1 second, this function where agents is declared has already completed and the agents variable is no longer accessible.

 $( "#runSimBtn" ).click(function runSimulation() {
        $( "#lContent h2" ).text("Simulation in progress...");

        var agents = $( "div.tooltipBox" );
        var falloutTimes = $( ".rFO" );
        var timeoutFunction = function(agent){
            agent.animate({ backgroundColor: "#FF0000" }, 500);
        }

        var i, j = 0;

        for(i = 0, j = 0; i < agents.length, j < falloutTimes.length; i++, j++) {
            var ttl = falloutTimes[j].value;

            if((ttl != undefined) && (ttl != 999)) {
                setTimeout(timeoutFunction(agents[i]), ttl*1000);
            } else {
                continue;
            }
        }
    });

as far as storing div selector in a variable is a concern, it works for me:

<div class="aClass">div 1</div>
<div class="aClass">div 2</div>

and jQuery:

var agents = $("div.aClass");
$(agents).each(function(key, val) {
    alert($(val).text());
});

will alert div 1 and div 2

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top