在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和wait,但什么都做不到干杯

您可以在任何您喜欢的地方等待承诺。您也可以在任何您喜欢的地方添加事件侦听器,但您必须处理事件已经发生的情况,尤其是在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>

最新更新