簡體   English   中英

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 處理程序中使用的任何變量都必須傳遞到實際的 function 閉包中,以便它們對每個不同的 onload 處理程序唯一可用。 有幾種方法可以做到這一點。

這種方式使用 function 閉包來捕獲傳入的值並使其可用於 onload function 處理程序:

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 中,此方法所做的是將執行匿名 function 調用的返回值分配給 onload 屬性。 該匿名 function 調用將 coName 參數傳遞給它。 function 返回另一個匿名 function ,它被分配為 onload 處理程序。 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. 可以把它想象成一個 function 的實例,它周圍有 state(局部變量的值),每次設置時都會唯一捕獲。 在這種情況下,它捕獲 coName 變量的值並將其放入閉包中,在該閉包中它變得唯一,並且不會受到后續對 for 循環中外部 coName 變量的更改的影響。

另一種方法是將參數放在實際的 object 上,以便您可以從那里檢索它:

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 將始終是執行任何 function 時的最后一個數組值。 你可以這樣做:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM