javascript - DOM 准备好前获取 DOM 准备好后回调
问题描述
背景
我正在使用 openweathermap 来显示曼彻斯特的当前温度和状况,代码运行良好。
HTML
<div class="wp-block-pbf-block-weather" data-key="*******************" data-city="2643123">
<p>The Current Weather in <span id="city">Manchester</span>
is <span id="temp">probably 13</span>°C
with <span id="condition">doom and gloom</span>
</p>
</div>
Javascript
function weatherBalloon( cityID, APIkey ) {
fetch('https://api.openweathermap.org/data/2.5/weather?id=' + cityID+ '&appid=' + APIkey)
.then(function(resp) { if (!resp.ok) {
throw new Error('Network response was not ok');
}
return resp.json() }) // Convert data to json
.then(function(data) {
document.getElementById("temp").innerHTML = Math.round(data.main.temp - 273.15);
document.getElementById("condition").innerHTML = data.weather[0].description;
console.log(data);
var cat = "part_cloud"; // set default weather category
var id = data.weather[0].id;
if (id >= 200 && id <= 299) { cat = "thunder"};
if (id >= 300 && id <= 399) { cat = "rain"};
if (id >= 500 && id <= 531) { cat = "rain"};
if (id >= 600 && id <= 699) { cat = "snow"};
if (id >= 700 && id <= 799) { cat = "fog"};
if (id == 800 ) { cat = "sun"};
if (id >= 801 && id <= 802) { cat = "part_cloud"};
if (id >= 803 && id <= 804) { cat = "cloud"};
var video = window.location.origin + "/wp-content/uploads/bg_video_" + cat + ".mp4";
console.log(video);
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
console.log ("OH NO Something Has Gone Wrong!")
});
}
(function($){
$(document).ready( function(){
var cityID = $('.wp-block-pbf-block-weather').data('city');
var APIkey = $('.wp-block-pbf-block-weather').data('key');
weatherBalloon( cityID, APIkey );
});
})(jQuery);
问题
因为我在 dom 准备好之后调用了 weatherBalloon 函数,所以 JS 使用从 api 接收的值更新默认 html 存在明显的延迟。
需要帮助
如何在 dom 准备好之前调用 fetch 并在 dom 准备好后让回调更新 html 以便希望删除/减少更新 html 的可见延迟?我尝试过使用 async 和 await ,但什么也做不了 干杯!
解决方案
你可以在任何你喜欢的地方等待一个承诺。你也可以在任何你喜欢的地方添加一个事件监听器,但是你必须处理事件已经发生的情况,尤其是当涉及到 DOM 就绪时。这是后一种选项的工作示例:
<html>
<body>
<script>
// more about docReady: https://stackoverflow.com/questions/9899372/
function docReady(fn) {
if (document.readyState === "complete" || document.readyState === "interactive") {
console.log('document already ready');
setTimeout(fn, 1);
} else {
console.log('adding event listener');
document.addEventListener("DOMContentLoaded", fn);
}
}
// the function to be called on "DOM ready"
function showData(data) {
const output = document.getElementById('output');
output.innerHTML = JSON.stringify(data);
}
// self executing function (async/await style)
!async function() {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const data = await response.json();
console.log(data);
docReady(showData(data));
}();
</script>
<div id="output"></div>
</body>
</html>
推荐阅读
- authentication - 有没有办法在不使用数据库的情况下在 Blazor 中进行外部身份验证?
- javascript - 如何创建一个对事件做出反应以加载更多数据的钩子?
- c++ - push_back 是否改变了存储在其向量中的类型的结构?
- reactjs - 在 Gatsby 中使用 GraphQL 和 React 进行小型 API 查询
- html - 引导列不在容器中,并且它们之间没有空间
- java - 可以每天自动更新 CSS 文件吗?
- javascript - 如何在我的网站上以视频为背景绘制字母形状?
- javascript - 如何分别发布/安装开发和生产环境的 npm 包
- php - 奇怪的 PHP 会话变量和缓存问题从今天 2020 年 8 月 14 日开始
- apache-camel - 使用 Apache Camel,将 XMLGregorianCalendar 转换为 ZonedDateTime