[英]Cannot set innerHTML inside setTimeout
試圖設置一個HTML類的innerHTML,它們是四個盒子,每個盒子一個接一個地設置3秒。 當innerHTML設置為加載圖標時,我可以在不使用setTimeout的情況下設置innerHTML。 當innerHTML放在setTimeout中時,返回以下內容:'Uncaught TypeError:無法設置undefined'的屬性'innerHTML'。
試圖調試我的代碼發送消息到控制台和搜索stackoverflow但沒有運氣。
var x = document.getElementsByClassName("numberBox");
for (var i = 0; i < 4; i++) {
x[i].innerHTML= '';
x[i].innerHTML= "<div class='loader'></div>"
}
// function to generate array of 4 random numbers
var randomNums = generateRandomNumbers();
for (var i = 0; i < 4; i++) {
setTimeout(function () {
x[i].innerHTML= '';
x[i].innerHTML = randomNums[i];
}, 3000 * i);
}
想知道為什么我的innerHTML不能在setTimeout中設置這里以及我的問題的可能解決方案。
我認為這是目前范圍的問題。 setTimeout函數創建自己的范圍,該范圍沒有引用舊變量。 您可能需要重新定義超時內的x或將數組顯式傳遞給超時。
請參閱此處了解操作方法: 如何將參數傳遞給setTimeout()回調?
我還建議你閱讀關閉器: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
當您使用var
for循環里面setTimeout
實際上是觸發的最后一個值i
在var
綁定只發生一次。
這是因為當整個循環完成時會觸發setTimeout
,然后你的i
將為4
。 請記住,由於您在setTimeout
調用中傳遞的回調函數,因此存在閉包。 那個閉包現在將指的是i
的最終值為4。
所以在這種情況下,當完成循環執行時, i
值為4
但x中的索引最多為3
。 這就是為什么當你嘗試訪問x[4]
你會得到undefined
,你會看到TypeError
來解決這個問題,只需使用let
在每次迭代中重新綁定i
的新值:
for (let i = 0; i < 4; i++) {
setTimeout(function () {
x[i].innerHTML= '';
x[i].innerHTML = randomNums[i];
}, 3000 * i);
}
此外,如果由於瀏覽器不兼容而無法使用let
,您可以使用IIFE執行此操作:
for (var i = 0; i < 4; i++) {
(function(i){
setTimeout(function () {
x[i].innerHTML= '';
x[i].innerHTML = randomNums[i];
}, 3000 * i);
})(i);
}
這是因為var
具有函數作用域,因此在每次迭代中都會創建一個新的作用域以及具有對i
的新值的新綁定的函數。
由於缺少i參數 - 超時可能使用last(4),這是在數組之外。
但您可以通過添加下一個超時參數來設置和使用函數參數。
var x = document.getElementsByClassName("numberBox"); for (var i = 0; i < 4; i++) { x[i].innerHTML= ''; x[i].innerHTML= "<div class='loader'></div>" } // function to generate array of 4 random numbers var randomNums = generateRandomNumbers(); for (var i = 0; i < 4; i++) { setTimeout(function (i) { x[i].innerHTML= ''; x[i].innerHTML = randomNums[i]; }, 3000 * i, i); } function generateRandomNumbers() { var retVal = []; for (var i = 0; i < 4; i++) { retVal.push(Math.random()); } return retVal; }
<div class="numberBox"></div> <div class="numberBox"></div> <div class="numberBox"></div> <div class="numberBox"></div>
// function to generate array of 4 random numbers
var x = document.getElementsByClassName("numberBox");
var randomNums = generateRandomNumbers();
for (var i = 0; i < 4; i++) {
setTimeout(function () {
x[i].innerHTML= '';
x[i].innerHTML = randomNums[i];
}, 3000 * i, x);
}
這個問題與一個非常基本和流行的Javascript概念有關,稱為閉包 。 它可以通過至少兩種方式解決:
let
var x = document.getElementsByClassName("numberBox");
for (let j = 0; j < 4; j++) {
x[j].innerHTML= '';
x[j].innerHTML= "<div class='loader'></div>"
}
// function to generate array of 4 random numbers
var randomNums = generateRandomNumbers();
for (let i = 0; i < 4; i++) {
setTimeout(function () {
x[i].innerHTML= '';
x[i].innerHTML = randomNums[i];
}, 3000 * i);
}
var x = document.getElementsByClassName("numberBox");
for (var i = 0; i < 4; i++) {
x[i].innerHTML= '';
x[i].innerHTML= "<div class='loader'></div>"
}
// function to generate array of 4 random numbers
var randomNums = generateRandomNumbers();
for (var i = 0; i < 4; i++) {
setTimeout((function (j) {
x[j].innerHTML= '';
x[j].innerHTML = randomNums[j];
})(i), 3000 * i);
}
您正試圖在內部方法中訪問x
,即x未在setTimeout
范圍內定義,這就是您接收該execption的原因
我建議你使用setInterval
函數作為解決方案你的代碼:
var randomNums = generateRandomNumbers();
for (var i = 0; i < 4; i++) {
setTimeout(function () {
x[i].innerHTML= '';
x[i].innerHTML = randomNums[i];
}, 3000 * i);
}
一個解決方法
var randomNums = generateRandomNumbers();
let i = 0;
let interval = setInterval(function() {
if( i != 2){
x[i].innerHTML= '';
x[i].innerHTML = randomNums[i];
i += 1;
} else {
clearInterval(interval) ;
}
}, 3000);
這個問題似乎是由幾個因素造成的。
setTimeout()
范圍之外定義generateRandomNumbers()
函數。 for
循環中使用var
定義。 function generateRandomNumbers() {
return Math.floor(Math.random() * 999999) + 10000;
}
var x = document.getElementsByClassName("numberBox");
for (var i = 0; i < x.length; i++) {
x[i].innerHTML= '';
x[i].innerHTML= "<div class='loader'></div>"
}
for (let i = 0; i < x.length; i++) {
setTimeout(function() {
x[i].innerHTML= '';
x[i].innerHTML = generateRandomNumbers();
}, 3000 * i);
}
這是一個不同的實現,但這是一個小提琴
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.