L oop через элементы, которые были добавлены асинхронно - PullRequest
0 голосов
/ 21 февраля 2020

Я хочу l oop через Элементы, которые были добавлены асинхронно с использованием 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;               

        })
    }

Вот где я нахожу проблему с l oop вокруг элементов, чтобы получить значения 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();

1 Ответ

0 голосов
/ 21 февраля 2020

Звучит так, как будто вы не ожидаете заполнения DOM результатом асинхронного вызова перед выполнением вычисления GPA.

Вы также можете использовать 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>
...