等待图像加载JavaScript

时间:2010-02-26 14:09:19

标签: javascript image load wait

我正在进行Ajax调用,它会返回一些信息,包括图像路径。

我在HTML中准备了所有这些信息,这些信息将显示为一种弹出窗口。我只是将弹出式div的可见性从隐藏切换为可见。

要设置弹出窗口的位置,我必须根据图像的高度进行计算。因此,在设置位置和将可见性切换为可见之前,我必须等待图像加载以了解其尺寸。

我尝试使用递归,setTimeout,完成img属性,而循环...没有成功。

那么,我该怎么做呢?也许我应该在Ajax调用中返回维度。

6 个答案:

答案 0 :(得分:101)

var img = new Image();
img.onload = function() { alert("Height: " + this.height); }
img.src = "http://path/to/image.jpg";

请注意,按上述顺序执行此操作非常重要:首先附加处理程序,然后设置src。如果你反过来这样做,并且图像在缓存中,你可能会错过这个事件。 JavaScript在浏览器中的单个线程上运行(除非您使用的是Web工作者),但 browsers 不是单线程的。浏览器看到src,识别资源是否可用,加载它,触发事件,查看元素是否有任何需要排队等待回调的处理程序,看不到任何资源,这对浏览器来说是完全有效的。 ,并在src行和附加处理程序的行之间完成事件处理。 (如果注册后行之间不会发生回调,它们会在队列中等待,但如果没有,则不需要等待事件。)

答案 1 :(得分:11)

如果您使用jQuery,则可以使用其load事件。

看看这个例子:

$('img.userIcon').load(function(){
    if($(this).height() > 100) {
        $(this).addClass('bigImg');
    }
});

答案 2 :(得分:3)

只需将图像加载区包装到带有promise的函数中,然后使用await进行调用即可。

async drawImg(ctx, image){

    return new Promise(resolve => {

          image.onload = function () {
                ctx.drawImage(image, 10, 10, 200, 180);
                resolve('resolved');
             }

    });

  }

它应该可以正常工作

答案 3 :(得分:1)

accepted answer 已过时,但确实显示了基本的 Image#onload 回调方法。如今,您可能希望承诺图像加载以避免回调地狱。

This answer 是承诺图像加载处理程序的好方法,但缺少 my comment 所指示的一些关键点。

这是 Image 的另一个更一般的承诺。在 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)
  );
});

答案 4 :(得分:1)

窗口加载事件怎么样?

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

这对我有用,我需要浏览器在运行布局脚本之前计算图像的大小。

答案 5 :(得分:-1)

我在我的页面上加载了一个缓慢的CAPTCHA(1st_image)图像,我想在加载CAPTCHA图像(1st_image)之后才显示另一个图像(2nd_image)。所以我不得不等待首先加载CAPTCHA(1st_image)图像。

这个解决方案非常适用于等待图像首先加载然后加载另一个图像(不要忘记显示"请等待!"图像等待要加载其他图像):

Import-Csv

互联网速度慢或快,浏览器将等待整个页面加载所有图像(即使它们是外部链接)然后执行该功能,因此第二个图像仅在第一张图片装好了。

高级注释:您可以在" src"中使用网页网址。首先加载网页然后显示图像的图像。目的是从外部网页加载cookie,这可能会影响显示的第二个图像(如CAPTCHA)