为何直接操作DOM的JS代码正常,先存元素变量再操作却失效?
问题:两段逻辑一致的天气应用代码,为何后者无法运行?
我正在使用OpenWeather API开发一款简易天气应用,以下代码片段可以正常运行:
//In the code below I'm using the open weather API to make a simple weather app const showWeatherData = (weatherData) => { document.getElementById("city-name").innerText = weatherData.name; document.getElementById("weather-type").innerText = weatherData.weather[0].main; document.getElementById("temp").innerText = weatherData.main.temp; document.getElementById("min-temp").innerText = weatherData.main.temp_min; document.getElementById("max-temp").innerText = weatherData.main.temp_max; };
但下面的代码片段却无法运行:
const cityName = document.getElementById("city-name"); const weatherType = document.getElementById("weather-type"); const temp = document.getElementById("temp"); const minTemp = document.getElementById("min-temp"); const maxTemp = document.getElementById("max-temp"); const showWeatherData = (weatherData) => { //CODE GOES HERE cityName.innerText = weatherData.name; weatherType.innerText = weatherData.weather[0].main; temp.innerText = weatherData.main.temp; minTemp.innerText = weatherData.main.temp_min; maxTemp.innerText = weatherData.main.temp_max; }
两者逻辑一致,为何后者无法运行?这是我首个JavaScript课程的学习内容,我原本以为可以先存储DOM元素变量再进行操作,难道并非如此?
解答
核心问题出在DOM元素的加载时机上:
- 第一段代码里,
document.getElementById是在showWeatherData函数内部执行的——这个函数应该是在API请求完成、DOM已经完全加载后才被调用的,此时页面上的目标元素已经存在,所以能正常获取并修改内容。 - 第二段代码里,你在脚本最顶部就直接执行了
document.getElementById去获取DOM元素,如果你的JavaScript代码是放在HTML文档的<head>标签里,或者放在页面元素之前,那么此时浏览器还没渲染出那些city-name、weather-type等元素,这些变量会被赋值为null。后续调用showWeatherData时,尝试给null.innerText赋值就会抛出错误,导致代码无法运行。
你原本的思路(先存储DOM元素变量再操作)是完全正确的,只是需要调整变量的初始化时机:
- 把脚本放在HTML文档的末尾(
</body>标签之前),确保DOM元素都渲染完成后再执行获取元素的代码; - 或者将获取元素的代码包裹在
DOMContentLoaded事件监听里,等待DOM加载完成后再执行:
let cityName, weatherType, temp, minTemp, maxTemp; document.addEventListener('DOMContentLoaded', () => { cityName = document.getElementById("city-name"); weatherType = document.getElementById("weather-type"); temp = document.getElementById("temp"); minTemp = document.getElementById("min-temp"); maxTemp = document.getElementById("max-temp"); }); const showWeatherData = (weatherData) => { cityName.innerText = weatherData.name; weatherType.innerText = weatherData.weather[0].main; temp.innerText = weatherData.main.temp; minTemp.innerText = weatherData.main.temp_min; maxTemp.innerText = weatherData.main.temp_max; }
另外注意第二段代码里的箭头函数末尾少了分号,不过这不是导致无法运行的核心原因,只是编码规范问题。
内容的提问来源于stack exchange,提问作者Yahya Nazeer
相关产品推荐
相关产品推荐

