How can I use the jQuery.on () method in a loop without overriding the objects I loop on

I need to assign mousedown events to a collection of objects.

But the .on () method seems to override my objects at every step.

Here is a very simplified example of what I have in my code.

Javascript:

$(document).ready(function() { var myArray = { 0: {"id": "box1", "color": "blue"}, 1: {"id": "box2", "color": "green"} }; for (i in myArray) { box = $('div#'+myArray[i]['id']); color = myArray[i]['color']; box.data('color', color); box.on({ mousedown: function() { var color = myArray[i]['color']; $(this).css({'background': $(this).data('color')}); myArray[i]['color'] = (i==0) ? "orange" : "pink"; } }); } }); 

and HTML:

 <div id="container"> <div id="box1"></div> <div id="box2"></div> </div> 

Alternatively, you can see this in action here: http://jsfiddle.net/ae3En/6/

Hope someone can help me, thanks.

+4
source share
6 answers

You can use .each to iterate over an array and prevent all scope issues with this:

 $.each(myArray, function(i, obj) { $('div#'+obj['id']).on({ mousedown: function() { $(this).css({'background': obj['color']}); } }); } 
+1
source

Because you use box in a function (and box is defined externally). That way, it will always refer to the last linked box. Has nothing to do with .on . A few ways to handle this, but the easiest way:

 mousedown: function () { $(this).css(...) } 

EDIT: I'm not quite sure why it only uses the last color from the variable. I was able to get around this by binding the expected color to the div itself using .data . We hope that this solution will work for you:

http://jsfiddle.net/ae3En/5/

+1
source

SMALL CHANGE IN YOUR CODE: REPLACE THIS LINE

 box.css({'background': myArray[i]['color']}); 

by

  $(this).css({'background': myArray[i]['color']}); 
+1
source

Your mousedown code does not run until the loop starts, so you always assign the last object. This works: jsFiddle example .

 var myArray = { "0": { "id": "box0","color": "blue" }, "1": {"id": "box1", "color": "green" } }; $('#container div').each(function(i) { $(this).on({ mousedown: function() { $(this).css({ 'background': myArray[i]['color'] }); } }) });​ 
+1
source

you can also send the current window variable to the listener function:

 $(document).ready(function() { var myArray = { "0": {"id": "box1", "color": "blue"}, "1": {"id": "box2", "color": "green"} }; function listener(box,i) { box.on({ mousedown: function() { box.css({'background': myArray[i]['color']}); } }); } for (i in myArray) { var box = $('div#'+myArray[i]['id']); listener(box,i); } }); 
0
source
 $(document).ready(function() { var myArray = { "0": {"id": "box1", "color": "blue"}, "1": {"id": "box2", "color": "green"} }; for (i in myArray) { var box = $('div#'+myArray[i]['id']); var color = myArray[i]['color']; box.data('color', color); box.on({ mousedown: function() { $(this).css({'background': $(this).data('color')}); } }); } }); 

Demo

0
source

All Articles