我可能错误地JavaSript
如何在for loop
中分配属性,我该如何解决这个问题呢?
var setImageSize = function (i) {
instances[i].img = $('<img id="jquery-background-zoom-'+i+'"/>');
var img = instances[i].img;
img.hide();
img.bind('load', function(e) {
var id = parseInt($(this).attr('id').replace('jquery-background-zoom-', ''));
instances[id].settings.bg.width = parseInt($(this).width());
instances[id].settings.bg.height = parseInt($(this).height());
$('#debug').html($('#debug').html() + '[' + i + ' ' + instances[id].settings.bg.width + ', ' + instances[id].settings.bg.height + ']<br>');
updateDefaultValues(instances[id]);
$(this).remove();
});
$('body').append(img);
img.attr('src', instances[i].settings.bg.url);
}
var setEvent = function (i) {
return function (e) {
var inst = instances[$(this).index()];
$('#debug').html(i + ' ' + inst.settings.bg.url);
$(this).bind('mousemove', {i:instances[$(this).index()]}, setFollowMouse);
}
}
var init = function (options) {
for (var i = 0; i < this_obj.length; i ++) {
instances.push ({id:i, element:this_obj.get(i), settings:$.extend(true, defaults, options)});
instances[i].settings.bg.url = $(this_obj.get(i)).css('background-image').replace('url(', '').replace(')', '').replace(/'/g, '').replace(/"/g, '');
$('#debug').html($('#debug').html() + '<br>' + i + ' -- ' + instances[i].toSource() + '<br><br>');
setImageSize (i);
$(instances[i].element).hover(setEvent(i), function () {
$(this).unbind('mousemove', setFollowMouse);
zoomOut($(this).index());
});
}
}
init(); // at the bottom of jQuery plug-in
在first test
我得到了我的期望:
({id:0, settings:{url:"http://localhost/js/img/example_0.jpg", other_propos:'relative to the id 0'}})
({id:1, settings:{url:"http://localhost/js/img/example_1.jpg", other_propos:'relative to the id 1'}})
({id:2, settings:{url:"http://localhost/js/img/example_2.jpg", other_propos:'relative to the id 2'}})
在event test
中的,当我调用mousemove
事件时,我只获得last element propos
但只获得id
,为什么?
({id:0, settings:{url:"http://localhost/js/img/example_2.jpg", other_propos:'relative to the id 2'}})
({id:1, settings:{url:"http://localhost/js/img/example_2.jpg", other_propos:'relative to the id 2'}})
({id:2, settings:{url:"http://localhost/js/img/example_2.jpg", other_propos:'relative to the id 2'}})
我不确定我在这里缺少什么,我怎么能避免这个?
我怀疑问题可能出在setImageSize
方法中,该方法加载了img
元素background image
,需要保存真正的width
和height
。< / p>
是否会出现负载延迟?
我不确定因为测试会在for循环中讨论错误的道具分配。
这里是http://jsfiddle.net/tonino/CFPTa/我确定问题出在jquery load事件中,但我不确定如何解决它。
答案 0 :(得分:3)
你所写的内容的问题源于封闭效应。
在您的匿名悬停函数中,您指的是i
变量,但在所有迭代完成之前,不会调用该事件。当您在匿名函数中引用i
变量时,它不会像当时那样获取i
的副本 - 它只是使用对它的引用。这意味着当你递增i
变量时,你也会增加匿名函数引用的变量,所以在所有三次迭代之后,你所做的所有三个匿名函数都引用相同的{{1} }值:2。
我相信制作方法工厂方法会起作用,如下所示:
i
调用工厂方法时,返回的函数将在调用时捕获工厂函数的范围 - 这意味着var factory = function(i) {
return function (e) {
var inst = instances[$(this).index()];
// event test, here I get only the last instance propos but the right id, why??
$('#debug').html($('#debug').html() + '<br>' + inst.toSource() + '<br>');
$(this).bind('mousemove', {i:instances[$(this).index()]}, setFollowMouse); // e.data.id
}
}
for (var i = 0; i < this_obj.length; i ++) {
instances.push ({id:i, element:this_obj.get(i), settings:$.extend(true, defaults, options)});
instances[i].settings.bg.url = $(this_obj.get(i)).css('background-image').replace('url(', '').replace(')', '').replace(/'/g, '').replace(/"/g, '');
// first test
$('#debug').html($('#debug').html() + '<br>' + instances.toSource() + '<br>');
$(instances[i].element).hover(factory(i), function () {
$(this).unbind('mousemove', setFollowMouse);
zoomOut($(this).index());
});
}
变量现在不会更改。
有关详情,请参阅此帖子:http://msdn.microsoft.com/en-us/scriptjunkie/ff696765
答案 1 :(得分:0)
这与关闭有关。在循环完成之前,函数不会运行。您可以使用立即调用的函数来解决此问题。
// will awlays output 5
for (var i = 0, len = 5; i < len; i += 1) {
setTimeout(function () {
console.log(i);
}, 100);
}
// this is correct
for (i = 0, len = 5; i < len; i += 1) {
(function (i) { // notice the immediately invoked function
setTimeout(function () {
console.log(i);
}, 100);
}(i));
}