重新加载后,切换不适用于 DOM 渲染的 HTML 元素
我正在制作一个天气应用程序,我想单击一个按钮在英制和公制之间进行转换。我还有一个搜索栏,当我输入一个位置时,会出现一个下拉菜单,我可以单击其中一项,HTML 页面将重新加载新信息。
在单击任何下拉项(在页面上具有初始值)之前,切换按钮可以正常工作。但是,当我单击下拉项并重新加载页面后,该按钮仅适用于我直接写入 .html 文件的 HTML 元素。对于我通过 DOM 写入 HTML 的其他元素,它不起作用。
相关代码如下。
async function init (name) {
await fetchCurrentData(name)
const forecastHoursList = await hoursList(name)
document.querySelector('.forecast ul').innerHTML = renderHourlyForecast(forecastHoursList)
const forecastDailyList = await dailyList(name)
document.querySelector('.future ul').innerHTML = renderDailyForecast(forecastDailyList)
}
// initial value
await init('Miami')
// toggle function below
const button = document.querySelector('button')
const hidden = document.querySelectorAll('span.hidden')
const visible = document.querySelectorAll('span.toggle')
button.addEventListener('click', event => {
hidden.forEach(el => {
el.classList.toggle('hidden')
el.classList.toggle('toggle')
})
visible.forEach(el => {
el.classList.toggle('hidden')
el.classList.toggle('toggle')
})
//Render data into HTML elements
const renderHourlyForecast = (forecastHoursList) => {
const renderedForecastList = forecastHoursList.map((el) => {
return `
<div>
<li>
<ul>
<li><h4>${el[0]}</h4></li>
<li><img src="${el[1]}"></li>
<li><span class="toggle" style="float: left">Temp °C</span><span class="hidden" style="float: left">Temp °F</span><h4 class="temp">${el[2]}</h4></li>
<li><span class="toggle" style="float: left">Feels °C</span><span class="hidden" style="float: left">Feels °F</span><h4 class="temp">${el[3]}</h4></li>
<li><span class="toggle" style="float: left">Wind kph</span><span class="hidden" style="float: left">Wind mph</span><h4 class="windspeed">${el[4]}</h4></li>
<li><span style="float: left">Cloud cover</span><h4>${el[5]}%</h4></li>
<li><span style="float: left">Precip chance</span><h4>${el[6]}%</h4></li>
</ul>
</li>
</div>
`
}).join('')
return renderedForecastList
}
//Searchbar input event below
const onInput = async event => {
const cityList = await autoComplete(event.target.value)
if(!cityList.length) {
dropdown.classList.remove('is-active');
return
}
resultsWrapper.innerHTML = ''
dropdown.classList.add('is-active');
for(let list of cityList) {
const option = document.createElement('a')
option.classList.add('dropdown-item')
option.innerHTML = renderOption(list)
//Dropdown click event below
option.addEventListener('click', async () => {
dropdown.classList.remove('is-active');
search.value = list[0];
await init(list[0])
});
resultsWrapper.appendChild(option)
}
}
I'm making a weather app and I want to click a button to convert between imperial and metric. I also have a search bar and when I enter a location, a dropdown menu would appear and I can click on one of the items and the HTML page would reload with new info.
Before clicking on any dropdown item (with initial values on the page), the toggle button works fine. But after I click on a dropdown item and the page reloads, the button works only for HTML elements that I wrote directly into the .html file. For the other elements that I wrote into HTML through DOM, it doesn't work.
Relevant code below.
async function init (name) {
await fetchCurrentData(name)
const forecastHoursList = await hoursList(name)
document.querySelector('.forecast ul').innerHTML = renderHourlyForecast(forecastHoursList)
const forecastDailyList = await dailyList(name)
document.querySelector('.future ul').innerHTML = renderDailyForecast(forecastDailyList)
}
// initial value
await init('Miami')
// toggle function below
const button = document.querySelector('button')
const hidden = document.querySelectorAll('span.hidden')
const visible = document.querySelectorAll('span.toggle')
button.addEventListener('click', event => {
hidden.forEach(el => {
el.classList.toggle('hidden')
el.classList.toggle('toggle')
})
visible.forEach(el => {
el.classList.toggle('hidden')
el.classList.toggle('toggle')
})
//Render data into HTML elements
const renderHourlyForecast = (forecastHoursList) => {
const renderedForecastList = forecastHoursList.map((el) => {
return `
<div>
<li>
<ul>
<li><h4>${el[0]}</h4></li>
<li><img src="${el[1]}"></li>
<li><span class="toggle" style="float: left">Temp °C</span><span class="hidden" style="float: left">Temp °F</span><h4 class="temp">${el[2]}</h4></li>
<li><span class="toggle" style="float: left">Feels °C</span><span class="hidden" style="float: left">Feels °F</span><h4 class="temp">${el[3]}</h4></li>
<li><span class="toggle" style="float: left">Wind kph</span><span class="hidden" style="float: left">Wind mph</span><h4 class="windspeed">${el[4]}</h4></li>
<li><span style="float: left">Cloud cover</span><h4>${el[5]}%</h4></li>
<li><span style="float: left">Precip chance</span><h4>${el[6]}%</h4></li>
</ul>
</li>
</div>
`
}).join('')
return renderedForecastList
}
//Searchbar input event below
const onInput = async event => {
const cityList = await autoComplete(event.target.value)
if(!cityList.length) {
dropdown.classList.remove('is-active');
return
}
resultsWrapper.innerHTML = ''
dropdown.classList.add('is-active');
for(let list of cityList) {
const option = document.createElement('a')
option.classList.add('dropdown-item')
option.innerHTML = renderOption(list)
//Dropdown click event below
option.addEventListener('click', async () => {
dropdown.classList.remove('is-active');
search.value = list[0];
await init(list[0])
});
resultsWrapper.appendChild(option)
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
之所以发生这种情况,是因为您使用
InnerHtml+=
作为dom
主要元素的子树已完全重建,事件处理程序被销毁。更好地使用event.target
检查单击元素是否是下拉元素。例如
This is happening because you used
innerHTML+=
as theDOM
Subtree of the main element is completely reconstructed, the event handlers are destroyed. Better use theevent.target
to check whether the element clicked is a dropdown element or not.For example