У вас будет очень распространенная проблема замыкания в цикле for in
.
Переменные, заключенные в замыкание, совместно используют одну и ту же среду, поэтому к тому времени mouseenter
вызывается функция обратного вызова, цикл завершит свой курс, а переменная id
останется, указывая на значение последнего элемента массива names
.
Это может быть довольно сложной темой, еслиВы не знакомы с тем, как работают замыкания.Вы можете прочитать следующую статью для краткого введения:
Это можно решить с помощьюеще больше замыканий с использованием фабрики функций:
function makeMouseEnterCallback (id) {
return function() {
console.log(id);
};
}
// ...
var id, k,
names = ['one','two','three'];
for (k = 0; k < names.length; k++) {
id = names[k];
$("#" + id).mouseenter(makeMouseEnterCallback(id));
}
Вы также можете встроить фабрику функций выше, как указано ниже:
var id, k,
names = ['one','two','three'];
for (k = 0; k < names.length; k++) {
id = names[k];
$("#" + id).mouseenter((function (p_id) {
return function() {
console.log(p_id);
};
})(id));
}
Любое другое решение может быть как @ dmпредлагается в другом ответе , заключая каждую итерацию в собственную область видимости:
var k,
names = ['one','two','three'];
for (k = 0; k < names.length; k++) {
(function() {
var id = names[k];
$("#" + id).mouseenter(function () { console.log(id) });
})();
}
Хотя это и не связано с этой проблемой, обычно рекомендуется избегать использования цикла for in
для итерации элементовмассив, как указано @ CMS в комментарии ниже ( Дальнейшее чтение ).Кроме того, явное завершение ваших операторов точкой с запятой также считается хорошей практикой в JavaScript.