Tom Gullen
Tom Gullen

Reputation: 61773

Jquery can't get my head around this

The alert(i) onclick bind line is run on 3 divs, but all of them when clicked alert the last set value of i. I hope what I'm trying to do makes sense, it's hard to explain. Instead of alerting 1,2 or 3, it alerts 3,3,3.

// Updates bar preview box
this.updatePropertyMarkerBox = function(self, BarsID) {

    ... snip ...

    // Loop  and add event handler
    for (var i = 0; i < self.bars[BarsIndex].markers.length; i++) {

        // Add click event
        $("#bmi-" + self.containerId + "-" + i).bind('click', function() {
            alert(i);
        });
    }

Upvotes: 3

Views: 189

Answers (4)

Ateş G&#246;ral
Ateş G&#246;ral

Reputation: 140182

On a tangent, a better way to add click handlers to multiple markers would be add a single click handler to just their container. The HTML could look something like:

<div id=#bmi-xxx">
    <div class="marker" data-marker="0">...</div>
    <div class="marker" data-marker="1">...</div>
    ...

You can use generic HTML5 data-* attributes to store arbitrary data.

And the JavaScript would be:

// Updates bar preview box
this.updatePropertyMarkerBox = function (self, BarsID) {

    ... snip ...

    // Add event handler
    $("#bmi-" + self.containerId).click(function (event) {
        var marker = $(event.target).attr("data-marker");

        if (marker) { // Hey, it's a marker!
            alert(marker);
        }
    });

Upvotes: 0

user113716
user113716

Reputation: 322622

While you could use invoke a function inside the loop, creating a new variable scope which captures the current value of i, an alternate approach would be to simply take the i value from the element's ID attribute:

for (var i = 0; i < self.bars[BarsIndex].markers.length; i++) {

    $("#bmi-" + self.containerId + "-" + i).bind('click', function() {
          //grab the number from the ID of the element
        alert( /\d+$/.exec( this.id )[0] );
    });
}

Example: http://jsfiddle.net/UGQA7/

Upvotes: 2

Nathan Romano
Nathan Romano

Reputation: 7106

    $("#bmi-" + self.containerId + "-" + i).bind('click', (function(i) {
        return function() {
            alert(i);
        };
    })(i));

Upvotes: 2

Robert
Robert

Reputation: 21388

When you're iterating in the for loop, you're essentially given the address to i, if you use it within the for loop at that very moment, it will be the value expected, however if you use it later (such as in a click event) it will point to the final incremented value of 3. To get the desired affect you can create an anonymous function, like so

for (var i = 0; i < self.bars[BarsIndex].markers.length; i++) (function(i) {

    // Add click event
    $("#bmi-" + self.containerId + "-" + i).bind('click', function() {
        alert(i);
    });
})(i)

Upvotes: 5

Related Questions