[英]Problem with getting e.target value from an asynchronous function
从异步 function 获取值然后在 e.target function 中使用它时,我遇到了一点问题。 我希望能够单击两个列表(姓名和姓氏)之一,然后在名为“结果”的 div 中显示结果。 我读了很多文章,但没有一篇能直接准确地解决我的问题:(我做错了什么?
async function getData() { let url = 'http://www.json-generator.com/api/json/get/cuSKqtKmgi?indent=2'; try { let res = await fetch(url); return await res.json(); } catch (error) { console.log(error); } } async function renderUsers() { const nameList = document.querySelector('.name-list') const surnameList = document.querySelector('.surname-list') let data = await getData(); let names = ''; let surnames = ''; data.person.forEach(user => { let htmlSegment = ` <li>${user.name}</li> `; names += htmlSegment; }); data.person.forEach(user => { let htmlSegment = ` <li>${user.surrname}</li> `; surnames += htmlSegment; }); nameList.innerHTML = names; surnameList.innerHTML = surnames; } const chooseUser = (e) => { const result = document.querySelector('.result') const origin = e.target; result.textContent = origin.textContent; } const showUser = () => { const menu = document.querySelectorAll('ul li') menu.forEach(element => { element.addEventListener('click', chooseUser) }); } renderUsers(); showUser()
nav{ display: flex; justify-content: flex-start; } ul li{ cursor: pointer; }
<nav> <ul class="name-list"> </ul> <ul class="surname-list"> </ul> </nav> <div class="result"></div>
如果有不清楚的地方随时问:)
renderUsers().then(r=>{
showUser()
})
为什么?:
renderUsers
是异步的 function
因此,如果没有then(... )
, showUser()
将在渲染项目之前调用。 所以, const menu = document.querySelectorAll('ul li')
将返回空列表
我会在这个程序中修复很多事情 -
.innerHTML
构建复杂的文档会强制所有数据通过 String 接口 const getJSON = url => // <- generic fetch(url).then(r => r.json()) function li(text) { const e = document.createElement("li") // <- use DOM api e.textContent = text return e // <- returns value } function appendUsers(elem, users) { const names = elem.querySelector(".name-list") const surnames = elem.querySelector(".surname-list") for (const u of users) { names.appendChild(li(u.name)) // <- DOM api surnames.appendChild(li(u.surrname)) } } const showUser = (elem, name) => elem.textContent = name async function main(url) { const nav = document.querySelector("nav") // <- once const result = document.querySelector("#result") // <- once const data = await getJSON(url) // <- generic appendUsers(nav, data.person) // <- synchronous nav.addEventListener("click", e => { showUser(result, e.target.textContent) }) } main("http://www.json-generator.com/api/json/get/cuSKqtKmgi?indent=2").catch(console.error) // <- err handler
nav{ display: flex; justify-content: flex-start; } ul li{ cursor: pointer; }
<nav> <ul class="name-list"> </ul> <ul class="surname-list"> </ul> </nav> <div id="result"></div>
那么renderUsers
是异步的,因此在您调用showUser
时没有要选择的li
元素。 您可以在renderUsers
结束时调用showUser
,或者只创建异步块并等待renderUsers
先解决。
async function getData() { let url = 'https://www.json-generator.com/api/json/get/cuSKqtKmgi?indent=2'; try { let res = await fetch(url); return await res.json(); } catch (error) { console.log(error); } } async function renderUsers() { const nameList = document.querySelector('.name-list') const surnameList = document.querySelector('.surname-list') let data = await getData(); let names = ''; let surnames = ''; data.person.forEach(user => { let htmlSegment = `<li>${user.name}</li>`; names += htmlSegment; }); data.person.forEach(user => { let htmlSegment = ` <li>${user.surrname}</li>`; surnames += htmlSegment; }); nameList.innerHTML = names; surnameList.innerHTML = surnames; } const chooseUser = (e) => { const result = document.querySelector('.result') const origin = e.target; result.textContent = origin.textContent; } const showUser = () => { const menu = document.querySelectorAll('ul li') menu.forEach(e => e.addEventListener('click', chooseUser)); } (async() => { await renderUsers(); showUser() })()
nav { display: flex; justify-content: flex-start; } ul li { cursor: pointer; }
<nav> <ul class="name-list"> </ul> <ul class="surname-list"> </ul> </nav> <div class="result"></div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.