循环通过异步添加的元素



我想循环使用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;               
})
}

在这里,我发现在元素周围循环以获得数据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();

这听起来像是在运行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>

最新更新