我正在执行 Ajax 调用,它会返回一些信息,包括图像路径。
我在我的 HTML 中准备了所有这些信息,这些信息将显示为一种弹出窗口。我只是将弹出 div 的可见性从隐藏切换到可见。
要设置弹出 div 的位置,我必须根据图像的高度进行计算。因此,在设置位置并将可见性切换为可见之前,我必须等待图像加载以了解其尺寸。
我尝试了递归、setTimeout、完整的 img 属性、while 循环……但没有成功。
那么,我该怎么做呢?也许我应该在我的 Ajax 调用中返回维度。
我正在执行 Ajax 调用,它会返回一些信息,包括图像路径。
我在我的 HTML 中准备了所有这些信息,这些信息将显示为一种弹出窗口。我只是将弹出 div 的可见性从隐藏切换到可见。
要设置弹出 div 的位置,我必须根据图像的高度进行计算。因此,在设置位置并将可见性切换为可见之前,我必须等待图像加载以了解其尺寸。
我尝试了递归、setTimeout、完整的 img 属性、while 循环……但没有成功。
那么,我该怎么做呢?也许我应该在我的 Ajax 调用中返回维度。
var img = new Image();
img.onload = function() { alert("Height: " + this.height); }
img.src = "http://path/to/image.jpg";
请注意,按上述顺序执行此操作很重要:首先附加处理程序,然后设置src
. 如果您以相反的方式执行此操作,并且图像在缓存中,则您可能会错过该事件。JavaScript 在浏览器中的单线程上运行(除非您使用网络工作者),但浏览器不是单线程的。浏览器看到src
,识别资源可用,加载它,触发事件,查看元素以查看它是否有任何需要排队等待回调的处理程序,没有看到任何处理程序,并完成事件,这是完全有效的处理,所有之间src
线和附加处理程序的线。(如果它们被注册,回调就不会在行之间发生,它们会在队列中等待,但如果没有,则不需要事件等待。)
如果你使用 jQuery,你可以使用它的load事件。
看看这个例子:
$('img.userIcon').load(function(){
if($(this).height() > 100) {
$(this).addClass('bigImg');
}
});
只需将您的图像 onload 包装在一个带有 promise 的函数中,然后使用 await 调用它。
async drawImg(ctx, image){
return new Promise(resolve => {
image.onload = function () {
ctx.drawImage(image, 10, 10, 200, 180);
resolve('resolved');
}
});
}
它应该工作得很好
该接受的答案是过时的,但确实表明了基本的Image#onload
回调方法。如今,您可能希望Promise图像加载以避免回调地狱。
这个答案是Promise图像加载处理程序的好方法,但正如我的评论所指出的那样,缺少一些关键点。
这是另一个Image
更笼统的Promise。在onerror
处理程序中拒绝并将实际图像对象传递给解析器对于使函数的可重用性最小化很重要。
改进可能包括其他参数(crossOrigin
例如 )。一个settings
对象或提供一个Image
作为参数是另一种泛化函数的方法(设置src
触发请求,所以应该在添加处理程序后最后进行)。
const loadImage = src =>
new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = reject;
img.src = src;
})
;
loadImage("http://placekitten.com/90/100").then(image =>
console.log(image, `\nloaded? ${image.complete}`)
);
使用上述功能,Promise.all
可用于并行加载一批图像(Promise.allSettled
如果您想在某些图像未加载的情况下继续前进,则很有用)。
const loadImage = src =>
new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = reject;
img.src = src;
})
;
const imageUrls = [
"http://placekitten.com/85/150",
"http://placekitten.com/85/130",
"http://placekitten.com/85/110",
];
Promise.all(imageUrls.map(loadImage)).then(images => {
const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
const ctx = canvas.getContext("2d");
images.forEach((image, i) =>
ctx.drawImage(image, i * 90, 0, image.width, image.height)
);
});
窗口加载事件怎么样?
window.addEventListener('load', (event) => {
//do stuff with images
});
或者
window.onload = (event) => {
//do stuff with images
};
https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
这对我有用,我需要浏览器在运行布局脚本之前计算图像的大小。