【问题标题】:Loop through elements that was added asynchronously循环遍历异步添加的元素
【发布时间】:2020-02-21 15:51:06
【问题描述】:

我想遍历使用 fetch 异步添加的元素。有人可以帮忙吗?这是我尝试过的:

我如何添加元素

    const body = document.querySelector("body");

    body.onload = function(){
        //loads the list of subjects
        getSubjects().then((data) => {
            let subjectSrting = ""; //initialize variable that holds the html of all the subjects semester wise

            // loops around each semester                
            data.forEach(function(semester){                    

                subjectSrting += "<div class='semester'> <div class='title yearTitle'>"+ semester.year +"</div> <div class='title semesterTitle'>"+ semester.semester +"</div>";

                // loops around each subject for each semester
                semester.subjects.forEach(function (subject){
                    let dis = ""
                    if(subject.type != "C"){
                        dis = "disabledSub";
                    }
                    subjectSrting += "<div class='subject "+dis+"'> <div class='sub'><span class='code'>" + subject.code + "</span><span class='name'>" + subject.name + "</span></div> <div class='subCredits'>" + subject.cred + "</div> <div class='attempt'> <input type='checkbox' id='" + subject.code + "' checked><label for='" + subject.code + "'>1st</label> </div> <button type='button' data_gpv='-1'  class='subResult'>SELECT</button> </div>";
                });                    

                subjectSrting += "</div>";

            });                

            let form = document.querySelector(".home form");
            form.innerHTML = subjectSrting;               

        })
    }

在这里我发现循环元素以获取 data-gpv 值并查看附加的复选框是否被选中时遇到了麻烦:

    function calculateGpa(){
        let subjects = document.getElementsByClassName("home")[0].getElementsByClassName('subject');


        console.log(subjects.length); //logs 0, eventhough there are items in the HTMLCollection

        console.log(subjects); //logs a an HTMLCollection[] with the elements in it
        for(var i=0; i<subjects.length; i++){
            // get the gpv values and see if the chechbox is checked
            // cannot run this because subjects.length return 0
        }  
    }

    calculateGpa();

【问题讨论】:

  • 主题将是 DOM 节点 (developer.mozilla.org/en-US/docs/Web/API/HTMLCollection) 的集合,而不是数组。尝试使用const arr = [...subjects] 将其转换为数组。
  • 我认为这是一个重复的问题HTMLCollection showing 0 length
  • @ben 试过没用...
  • @asmaa 听起来很相似,但事实并非如此。我需要找到一种方法来循环我得到的 HTMLCollection...
  • 仔细检查您的选择器。如果长度为零,则说明您没有正确或在适当的时间检索 DOM 元素。

标签: javascript html asynchronous fetch htmlcollection


【解决方案1】:

这听起来像是在运行 GPA 计算之前,您没有等待 DOM 填充异步调用的结果。

您可以使用 Promise API (then) 来解决此问题,也可以向 onLoad 提供回调。

function onLoad() {
    getSubjects()
        .then((result) => {                 
            document.querySelector(".home").innerHTML = result              
        })
        .then(calculateGPA)
}

function getSubjects() {
    return new Promise((resolve) => setTimeout(() => resolve(`
        <div class="gpa">2.0</div>
        <div class="gpa">3.0</div>
    `), 3000))
}
    
function calculateGPA() {
    let total = 0
    const gpas = document.getElementsByClassName('home')[0].getElementsByClassName('gpa')

    console.log(gpas.length) // 2
    console.log(gpas) // HTMLCollection
    
    for(let g of [...gpas])
        total += Number(g.innerText)
        
    console.log(`The average gpa is: ${(total/gpas.length)}`) 
}


onLoad()
<div class="home">
 Waiting for GPAs...
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-09-30
    • 1970-01-01
    • 1970-01-01
    • 2012-11-23
    • 2016-05-29
    • 1970-01-01
    • 2017-12-12
    • 1970-01-01
    相关资源
    最近更新 更多