当 DOM 完成绘制新元素时发出警报的最简单方法是什么?



我只想禁用某些按钮并显示加载微调器,直到加载图像。 这是一个类似的问题 - 如何检测图像何时在浏览器中完成渲染(即绘制(? 我是javascript的新手,很困惑为什么没有一个简单的方法来确定这一点!类似这样的东西——

document.addEventListener('readystatechange', event => {
if (event.target.readyState === 'complete') {
alert('complete');
}
});

不幸的是,经过大量搜索,我似乎需要使用回调或承诺。我想现在是学习承诺/异步/等待的好时机。我很难尝试使用 promise 重写我的函数。

$('#container').on('click', '#imgSearch', function (e) {
$(this).html(`
<i class="fa fa-spinner fa-spin"></i>Loading`);
//various if statements here to check radio buttons
showImgs(search, sort, phpController, limit);
}

function showImgs(search, sort, phpController, limit) {
imgArray = [];
var a1 = $.post(phpController, {search: search, sort: sort, limit: limit}, {dataType: 'json'});
$.when(a1).done(function (response) {
if (response['error']) {
alert(response.error.img);
} else {
var imgs = response;
if (Array.isArray(imgs)) {
for (let i = 0; i < imgs.length; i++) {
//I use setTimeout here to render one image per second
setTimeout(function () {
offset++;
saveImages(imgs[i]);
//calling alertFinished on last img is my temporary solution to removing spinner after render
if (i === imgs.length - 1) {
alertFinished();
}
}, 1000 * i);
}
} else {
saveImages(imgs);
}
}
});
}
;

我使用 saveImages 函数清空并推送到另一个数组以及未显示的其他目的-

function saveImages(img) {
imgArray = [];
imgArray.push(img);
displayImages(imgArray);
}
;

displayImages在添加类等时渲染图像

-
function displayImages(imgs) {
var counter = 0;
imgs.forEach(img => {
var html = '';
html += `<div class="" id='${img.id}'><img src=${img.image}></div>`;
$(html).hide().appendTo(imgSection).fadeIn(1000);
});
}
;

警报已完成从搜索按钮中删除加载微调器。

function alertFinished() {
$('#imgSearch').text('Search');
}

有人可以解释一下在这种情况下如何使用承诺/异步/等待吗?不幸的是,没有办法使用类似于readystatechange的事件侦听器,因为另一种方法是重构在DOM中呈现新元素的每个函数,以禁用按钮,显示微调器等。显示微调器/加载味精是一项如此广泛的功能,我很惊讶我很难正确实现它。

因此,首先,正如您从链接到的问题(以及其中的评论(中看到的那样,没有一种很好的方法来判断图像何时实际绘制。因此,我将重点介绍一种在加载图像后调用某些函数的方法。

对于初学者来说,如果你的页面在第一次加载时有一堆图像,并且你只是想在做某事之前等待它们加载,你可以尝试超级简单的路线,这将是窗口加载事件。

window.addEventListener('load', (event) => {
// do stuff
});

但我的印象是,您正在动态添加图像并希望在加载图像后执行某些操作,因此这不起作用。不过,我认为你把事情复杂化了。快速浏览一下您的函数会发现您正在循环中调用saveImagesdisplayImages,即使它们似乎是您在完成添加图像后只想执行一次的操作。

假设在整个过程中的某个时刻,您发现自己有一堆已添加到DOM中的图像,至少其中一些仍在加载过程中,您需要做的是检查要加载的最后一个图像,然后删除加载微调器。

这里的诀窍是确定最后加载哪个图像。它不一定是您添加的最后一个,因为之前添加的图像可能会更大。

您可以使用一种方法来跳过整个承诺/异步混淆,方法是使用递归函数,该函数每隔一段时间检查是否加载了所有图像,如果没有,请稍等片刻,然后再次检查。如果您在函数再次调用自身之前等待的时间相对较短,这可能对您来说很好。

大致如下:

const registeredImages = [];
// add your images    
for (let i = 0, l = someImages.length; i < l; i += 1) {
doSomething(); // add someImages[i] to DOM where you want it
someImages[i].setAttribute('data-id', `image-${i}`); // or whatever way to keep track of it
someImages[i].addEventListener('load', register);
}
// remove spinner once they're loaded
tryToRemoveSpinner();
function register(event) {
images.push(event.target.getAttribute('data-id');
}
function tryToRemoveSpinner {
if (registeredImages.length === someImages.length) {
removeSpinner(); // or whatever
} else {
setTimeout(() => { tryToRemoveSpinner() }, 100);
}
}

您可以在此处添加的增强功能是在tryToRemoveSpinner上放置某种计数器,因此,如果某些图像由于某种原因无法加载,它最终只会纾困或运行removeSpinner()无论如何,或者在发生错误时您想做的任何事情,以防万一。


相关阅读:如何创建 JavaScript 回调以了解何时加载图像

最新更新