如何将JSON获取的赛事数据正确关联至对应容器div?
问题
尝试通过JSON请求展示赛事列表,功能基本正常,但无法将赛事对应的比赛正确关联至对应赛事标题下。错误表现为:第一个赛事容器显示所有赛事的比赛,第二个容器显示除第一个赛事外的所有比赛,第三个容器显示除前两个赛事外的所有比赛,以此类推。
当前代码如下:
function appendData(data) { var mainContainer = document.querySelector(".calendar-list"); for (var i = 0; i < data.competitions.length; i++) { mainContainer.innerHTML += `<div><p class="event">` + data.competitions[i].name + `</p></div>`; for (var j = 0; j < data.competitions[i].events.length; j++) { for (var x of document.querySelectorAll(".calendar-list>div")) { x.innerHTML += `<p class="match"><span>` + data.competitions[i].events[j].home.name + `</span><span>` + data.competitions[i].events[j].away.name + `</span><span>` + data.competitions[i].events[j].cutoffTime.slice(11, 16) + `</span></p>`; } } } }
预期的HTML结构(包含2个赛事及若干比赛):
<div class="calendar-list"> <div> <p class="event">World Cup</p> <p class="match"> <span>Cloud9 White Cloud</span><span>Guild X</span><span>17:00</span> </p> <p class="match"> <span>G2 Gozen</span><span>Liquid Brazil</span><span>17:00</span> </p> <p class="match"> <span>Cloud9</span><span>Guild X</span><span>17:00</span> </p> <p class="match"> <span>G2 Gozen White</span><span>Liquid Brazil</span><span>17:00</span> </p> </div> <div> <p class="event">Champions Tour: Game Changers Championship</p> <p class="match"> <span>Cloud9 White</span><span>Guild X</span><span>17:00</span> </p> <p class="match"> <span>G2 Gozen</span><span>Liquid Brazil</span><span>17:00</span> </p> </div> </div>
如何实现仅显示每个赛事对应的比赛列表?
解决方案
错误原因
原代码核心问题:处理某一赛事的比赛时,会选中所有已创建的赛事容器,将当前比赛添加到每一个容器中。随着循环推进,前面的容器会被重复添加后续所有赛事的比赛,最终出现题目中的错误。
修正后的代码(DOM节点操作方式)
function appendData(data) { var mainContainer = document.querySelector(".calendar-list"); for (var i = 0; i < data.competitions.length; i++) { // 创建当前赛事的专属容器,先插入标题 var eventContainer = document.createElement('div'); eventContainer.innerHTML = `<p class="event">${data.competitions[i].name}</p>`; // 仅将当前赛事的比赛添加到专属容器内 for (var j = 0; j < data.competitions[i].events.length; j++) { const match = data.competitions[i].events[j]; eventContainer.innerHTML += ` <p class="match"> <span>${match.home.name}</span> <span>${match.away.name}</span> <span>${match.cutoffTime.slice(11, 16)}</span> </p> `; } // 把组装好的赛事容器添加到主容器 mainContainer.appendChild(eventContainer); } }
修正后的代码(字符串拼接优化方式)
这种方式先在内存中拼接完整HTML,再一次性更新DOM,性能更优:
function appendData(data) { var mainContainer = document.querySelector(".calendar-list"); let html = ''; for (var i = 0; i < data.competitions.length; i++) { const competition = data.competitions[i]; // 拼接赛事标题和容器起始标签 html += `<div><p class="event">${competition.name}</p>`; // 拼接当前赛事的所有比赛 for (var j = 0; j < competition.events.length; j++) { const match = competition.events[j]; html += ` <p class="match"> <span>${match.home.name}</span> <span>${match.away.name}</span> <span>${match.cutoffTime.slice(11, 16)}</span> </p> `; } // 闭合赛事容器标签 html += `</div>`; } // 一次性插入所有内容到主容器 mainContainer.innerHTML = html; }
逻辑说明
- 为每个赛事创建专属容器,避免与其他赛事容器混淆;
- 仅将当前赛事的比赛添加到对应专属容器内,保证赛事与比赛的一一对应;
- 减少DOM操作次数,提升页面渲染效率。
内容的提问来源于stack exchange,提问作者igs
相关产品推荐
相关产品推荐

