Javascript 只为数组中的最后一项设置属性 [英] Javascript only sets attribute for last item in array

查看:25
本文介绍了Javascript 只为数组中的最后一项设置属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个大约 50 个项目的数组,在 javascript 中它会通过这个数组来检查条件,如果满足条件,它会为要检查的复选框设置属性.它完成得很好,但每次只更改数组中的最后一项.这是代码的一部分.

I have an array of ~50 items and in javascript it goes through this array to check a condition and if the condition is met it setsattribute for checkboxes on the be checked. It goes through nicely but only changes the very final item in the array every time. Here is a section of the code.

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;        
        }

    };

因此,您可以看到是否满足条件,它仍然会更改属性,但我收到的错误是它只更改数组中的最后一项.有什么想法吗?

So as you can see if the condition is met or not it will still change the attributes but the error I have been receiving is that it only changes the final item in the array. Any ideas?

推荐答案

这是 Javascript 中异步回调的经典问题.onload 处理程序将在一段时间后调用,在 for 循环完成很久之后,因此 for 循环中的索引被固定在它结束的末尾,局部变量 newImg 和 coName 将只有它们在循环中的最后一个值.

This is a classic issue with an asynchronous callback in Javascript. The onload handler will be called some time later, long after the for loop has finished, thus the index in the for loop is pegged at the end where it ended up and the local variables newImg and coName will only have their last values in the loop.

您希望在 onload 处理程序中使用的任何变量都必须传递到实际的函数闭包中,以便它们对每个不同的 onload 处理程序唯一可用.有几种方法可以做到这一点.

Any variables that you wish to use inside the onload handler will have to passed into the actual function closure so that they are uniquely available for each different onload handler. There are several ways to do that.

这种方式使用函数闭包来捕获传入的值并使其可用于 onload 函数处理程序:

This way uses a function closure to capture the passed in value and make it available to the onload function handler:

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 变量的后续更改的影响.

In Javascript-speak, what this method does is assign to the onload attribute the return value from executing an anonymous function call. That anonymous function call passed the coName parameter into it. That function returns another anonymous function which is what gets assigned as the onload handler. But, because of the way function closures work in javascript, the value of coName is captured in the function closure and is kept accessible to the onload handler for the duration of the function closure. One can think of it a little like an instance of a function with state around it (values of local variables) that is uniquely capture each time it's set up. In this case, it captures the value of the coName variable and puts it into the closure where it becomes unique and won't be effected by later changes to the outer coName variable that's in the for loop.

另一种方法是将参数放在实际对象上,以便您可以从那里检索它:

Another way to do it is to put the parameter on the actual object so you can retrieve it from there:

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;        
        }

    };
}

这篇关于Javascript 只为数组中的最后一项设置属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆