The reason, as already mentioned, is that the scope of i
is the same for both eventhandlers, and as such it will have the same value for both of them.
There is a couple of solution for this problem.
Solution 1: create a new scope via a immediate function
var pm = 2;
for (var i = 0; i < pm; i++) {
$("#specialty_pm_"+i).mouseenter(function(instance){
return function() { alert(instance); };
}(i));
};
You can see a fiddle of it in action here: http://jsfiddle.net/LP6ZQ/
Solution 2: use jQuerys data
method to store the value
var pm = 2;
for (var i = 0; i < pm; i++) {
$("#specialty_pm_"+i).data('instance',i).mouseenter(function(){
alert($(this).data('instance'));
});
};
You can see a fiddle of it in action here: http://jsfiddle.net/LP6ZQ/1/
Solution 3: bind
the instance number to the eventhandler
var pm = 2;
for (var i = 0; i < pm; i++) {
$("#specialty_pm_"+i).mouseenter(function(instance){
alert(instance);
}.bind(null,i));
};
You can see a fiddle of it in action here: http://jsfiddle.net/LP6ZQ/2/
Solution 3 has a few caveats - this
is being bound as null
, and thus it can no longer be used as a reference to the dom element, like jQuery eventhandlers nomrally do. Also bind
isn't supported by older browsers, but this can be mitigated by usinga polyfill, a good one can be found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
Solution 4: Be smart and use a delegate instead of binding event handlers in a loop
$(document.body).on('mouseenter','.specialty_pm',function(){
alert($(this).data('id'));
});
You can see a fiddle of it in action here: http://jsfiddle.net/LP6ZQ/4/
Solution 4 is the "right way" to do it, but it will require you to change the way you build your markup