Javascript只设置数组中最后一项的属性
Javascript only sets attribute for last item in array
我有一个大约50个项目的数组,在javascript中,它通过这个数组来检查一个条件,如果满足条件,它会在被检查的复选框上设置属性。它执行得很好,但每次只更改数组中的最后一项。下面是一段代码:
for (i = 0; i < urlArray.length; i++) {
var newImg = new Image();
var coName = companyArray[i];
newImg.onload = function(){
if (condition is met){
nStar++;
document.getElementById(coName).setAttribute("checked", "checked");
document.getElementById(coName).checked = true;
} else {
nStar++;
document.getElementById(coName).setAttribute("checked", "checked");
document.getElementById(coName).checked = true;
document.getElementById(coName).setAttribute("disabled", "disabled");
document.getElementById(coName).disabled = true;
}
};
所以你可以看到,如果条件满足与否,它仍然会改变属性,但我一直收到的错误是,它只改变了数组中的最后一项。什么好主意吗?
这是Javascript中异步回调的一个经典问题。onload处理程序将在一段时间后被调用,在for循环结束后很长一段时间,因此for循环中的索引将固定在它结束的末尾,而局部变量newImg和coName将只在循环中具有它们的最后值。
你希望在onload处理程序中使用的任何变量都必须传递到实际的函数闭包中,以便它们对每个不同的onload处理程序都是唯一可用的。有几种方法可以做到这一点。
这种方法使用函数闭包捕获传入的值,并使其可用于onload函数处理程序:
for (i = 0; i < urlArray.length; i++) {
var newImg = new Image();
var coName = companyArray[i];
newImg.onload = (function (coName) {
return function(){
if (condition is met){
nStar++;
document.getElementById(coName).setAttribute("checked", "checked");
document.getElementById(coName).checked = true;
} else {
nStar++;
document.getElementById(coName).setAttribute("checked", "checked");
document.getElementById(coName).checked = true;
document.getElementById(coName).setAttribute("disabled", "disabled");
document.getElementById(coName).disabled = true;
}
};
}) (coName);
}
在javascript中,这个方法的作用是将执行匿名函数调用的返回值赋给onload属性。该匿名函数调用将coName参数传递给它。该函数返回另一个匿名函数,该函数被分配为onload处理程序。但是,由于javascript中函数闭包的工作方式,coName的值在函数闭包中被捕获,并在函数闭包期间保持onload处理程序的可访问性。你可以把它想象成一个函数的实例,它周围有状态(局部变量的值),每次它被设置时都是唯一捕获的。在这种情况下,它捕获coName变量的值,并将其放入闭包中,使其成为唯一的,并且不会被以后对for循环中的外部coName变量的更改所影响。
另一种方法是将参数放在实际对象上,这样您就可以从那里检索它:
for (i = 0; i < urlArray.length; i++) {
var newImg = new Image();
newImg.setAttribute("coName". companyArray[i]);
newImg.onload = function() {
var coName = this.getAttribute("coName");
if (condition is met){
nStar++;
document.getElementById(coName).setAttribute("checked", "checked");
document.getElementById(coName).checked = true;
} else {
nStar++;
document.getElementById(coName).setAttribute("checked", "checked");
document.getElementById(coName).checked = true;
document.getElementById(coName).setAttribute("disabled", "disabled");
document.getElementById(coName).disabled = true;
}
};
}
问题是变量coName将始终是执行任何函数时的最后一个数组值。你可以这样做:
for (i = 0; i < urlArray.length; i++) {
var newImg = new Image();
var coName = companyArray[i];
newImg.onload = (function(name){
return function(){
if (true) {
nStar++;
document.getElementById(name).setAttribute("checked", "checked");
document.getElementById(name).checked = true;
} else {
nStar++;
document.getElementById(name).setAttribute("checked", "checked");
document.getElementById(name).checked = true;
document.getElementById(name).setAttribute("disabled", "disabled");
document.getElementById(name).disabled = true;
}
}
})(coName);
}
- 如何从对象数组中获取最后一项
- 为什么只有最后一项显示,而不是全部显示
- 删除最后一项jquery
- $q.all当输入数组中的一项不是promise时,Typescript检查器失败
- 为什么我的“for”循环只获取 html 中的最后一项
- 我无法将下拉列表的默认值设置为最后一项
- 流星批量插入仅插入最后一项
- 我怎么能知道元素是最后一项
- 如何删除WinJS组绑定列表的最后一项
- 在immutable.js中更改列表中的一项
- 使用handlers.js模板以数组中的最后一项为条件
- empty().append()追加循环中的最后一项
- jQuery只附加最后一项
- 将属性添加到 for 循环中的最后一项
- 我的应用仅显示一项检索到的数据
- 如何在 visjs 时间轴中按时间顺序获取 getVisibleItems(或如何获取上一项)
- 滑动视图 - 显示下一项的预览/片段
- 为数组的每一项添加一个额外的属性
- Javascript只设置数组中最后一项的属性
- 将属性移动到列表中的上一项