簡體   English   中英

在另一個函數中使用for語句JavaScript的函數

[英]function inside another function using for statement JavaScript

我的腳本有問題,控制台中沒有錯誤,但是沒有輸出。 我的代碼應在“示例”類的Divs中創建P元素,但我的“示例”類的div將保存在“背景”類的Divs中。

到目前為止,我有:HTML:

<div class="background">
<div class="example"><p class="num"></p></div>
<div class="example"><p class="num"></p></div>
</div>
<div class="background">
<div class="example"><p class="num"></p></div>
<div class="example"><p class="num"></p></div>
</div>
<div class="background">
<div class="example"><p class="num"></p></div>
<div class="example"><p class="num"></p></div>
</div>
<div class="background">
<div class="example"><p class="num"></p></div>
<div class="example"><p class="num"></p></div>
</div>

CSS:

body {
  display: inline-block;
  background-color: black;
  box-sizing: border-box;
}
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

.example {
  display: inline-block;
  position: absolute;
  color: orange;
  width: 100%;
  font-size: 30px;
  overflow: hidden;
  white-space: nowrap;

}
.background {
  display: inline-block;
  position: absolute;
  width: 100%;

}

.num {
  display: inline-block;
  color: orange;
  width: 5%;
  height: 50px;
  text-align: center;
  background-color: red;

}

JavaScript:

function background(){debugger;
var bg = document.getElementsByClassName("background");
var num;
for (var num=0; num < bg.length; num++ ){
    var line = bg[num].getElementsByClassName("example");
    var row ;
    for(var row=0; row < line.length; row++){
        var makeBoxInterval = setInterval(makeBoxes, 50);
        function makeBoxes(){

        var element =line[row].getElementsByClassName("num");
        var para = document.createElement("p");
        para.classList.add("num");
        var parent = line[row];
        var rowWidth = parent.offsetWidth;
        var boxesSoFar = element.length;
        var boxWidth = element.offsetWidth;
        var boxesInRow = rowWidth / boxWidth;
            if (boxesSoFar < boxesInRow) {
        parent.appendChild(para);
            } 
            else {
        clearInterval(makeBoxInterval);
         } 
    }
}
}
setInterval(function(){background()},100)
}

window.onload = function(){ 

  background();


}

我將JavaScript更改為:

function background(){debugger;
    var bg = document.getElementsByClassName("background");
    var num;
    for (let num=0; num < bg.length; num++ ){
        let line = bg[num].getElementsByClassName("example");
        let row ;
        for(let row=0; row < line.length; row++){
            let makeBoxInterval = setInterval(makeBoxes, 50);
            function makeBoxes(){

            let element =line[row].getElementsByClassName("num");
            let para = document.createElement("p");
            para.classList.add("num");
            let parent = line[row];
            let rowWidth = parent.offsetWidth;
            let boxesSoFar = element.length;
            let boxWidth = element.offsetWidth;
            let boxesInRow = rowWidth / boxWidth;
                if (boxesSoFar < boxesInRow) {
            parent.appendChild(para);
                } 
                else {
            clearInterval(makeBoxInterval);
             } 
        }
    }
    }
    setInterval(function(){background()},100)
    }

    window.onload = function(){ 

      background();


    }

但是還是沒有

任何想法如何將函數與外部函數中的for語句連接? 也許還有其他方法?

小提琴:

您的內部函數引用的rownum在函數執行時(異步)已經達到了最終值:這是因為兩個循環都將任何間隔觸發內部函數之前完成。 這只會在您的循環執行完所有迭代之后才開始發生。

對於您在函數中引用的其他變量(例如linemakeBoxInterval )也是如此:它們僅在外部函數本地,因此內部函數將引用分配給它們的最新值。

為了避免這種情況發生,請為您的變量(應聲明)提供一個塊范圍,即使用let

for (let num=0; num < bg.length; num++ ){
    let line = bg[num].getElementsByClassName("example");
    let row ;
    for(let row=0; row < line.length; row++){
        let makeBoxInterval = setInterval(makeBoxes, 50);
        // ...etc

現在,內部函數將引用rownum變量實例,這些實例對於循環的正確迭代而言是局部的。

其他事宜

您的代碼中還有其他幾個問題:

  • element是一個HTML元素列表,因此將沒有offsetWidth屬性。 您可能想從第一個元素中獲取該元素: element[0].offsetWidth
  • 您有兩個setInterval調用,這些調用將堆疊起來並最終使您的頁面掛起。 setTimeout是一種更安全的方法,因為您隨后將負責調用下一個setTimeout
  • 您的循環是同步的,但您希望具有異步效果。 在這種情況下,使用函數調用自身並使用下一個參數進行異步循環更為實用。
  • 您的CSS具有絕對定位,因此所有行都將出現在同一位置。 這意味着第二行的增長不會產生任何視覺效果。 我尚未解決此問題,因為我不知道您在可視化中的目的是什么。 但這不是您的問題的一部分,我認為您應該從這里開始:

 function background(){ const lines = Array.from(document.querySelectorAll(".background>.example")); (function makeBoxInterval(row) { if (row >= lines.length) return; // all done const parent = lines[row], element = parent.getElementsByClassName("num"), para = document.createElement("p"), rowWidth = parent.offsetWidth, boxesSoFar = element.length, boxWidth = boxesSoFar ? element[0].offsetWidth : 1, boxesInRow = rowWidth / boxWidth; para.classList.add("num"); if (boxesSoFar < boxesInRow) { parent.appendChild(para); setTimeout(makeBoxInterval.bind(null, row), 500); } else { makeBoxInterval(row+1); } })(0); } window.onload = background; 
 body { display: inline-block; background-color: black; box-sizing: border-box; } * { padding: 0; margin: 0; box-sizing: border-box; } .example { display: inline-block; position: absolute; color: orange; width: 100%; font-size: 30px; overflow: hidden; white-space: nowrap; } .background { display: inline-block; position: absolute; width: 100%; } .num { display: inline-block; color: orange; width: 5%; height: 50px; text-align: center; background-color: red; } 
 <div class="background"> <div class="example"><p class="num"></p></div> <div class="example"><p class="num"></p></div> </div> <div class="background"> <div class="example"><p class="num"></p></div> <div class="example"><p class="num"></p></div> </div> 

暫無
暫無

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

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