17

有人告诉我有必要在设置图像对象onload之前设置功能src。我已经在 SO 中搜索过这个。

我找到了这段代码:

var img = new Image();
img.src = 'image.jpg';
img.onload = function () {
    document.body.appendChild(img);
};

但大多数人认为onload应该这样写src

var img = new Image();
img.onload = function () {
    document.body.appendChild(img);
};
img.src = 'image.jpg';

必须按这个顺序写吗?是否存在上述代码会导致错误的情况(例如图像太大)?

如果有人能给我一些例子,我将不胜感激。

4

5 回答 5

9

它不是必须的,但是如果src在附加处理程序之前设置和图像加载,它不会触发。

JavaScript 以异步方式运行。设置src将导致 Web 浏览器在主执行流程之外加载图像。如果onload在操作完成时未设置 - 可能介于设置srconload.

于 2013-02-01T14:36:27.683 回答
5

一旦您为 src 分配了一个值,图像就会加载。如果它在达到 onload 之前加载,您的 onload 将不会触发。

为了支持所有实现,我强烈建议在设置 src 之前分配 onload 处理程序。

It is my experience (21+ years of JS) that you MUST set onload first - especially in IE which did not even support the image object when I started with JS.

If you get issues about the cached image not firing, add +"?"+new Date().getTime() when you set the src next time to avoid cache.

Here is the example from MDN which also uses the order I have suggested

Creating an image from scratch

Another SO link image.onload not firing twice in IE7

于 2013-02-01T14:39:09.227 回答
2

分配 src 后,浏览器将立即开始异步下载图像,因此下载可能会在您附加 onload 事件处理程序之前完成,并且永远不会触发代码以将图像添加到 DOM。

于 2013-02-01T14:37:48.857 回答
2

Most browser fire the load event imediatly if the image if the image is cached. However, Internet explorer 7 won't fire it at all. That's why it's better to set the src first.

于 2013-02-01T14:39:25.407 回答
0

Answers above always mentioned the same problem like:

there is the possibility the download could complete before you attach the onload event handler

or

but if setting the src and the image loads before your handler is attached, it won't fire.

or bug with IE7.

First, let's ignore IE7.

Second, I don't think problem mentioned exist, for example:

function loadImg(url) {
  let img = new Image()
  img.src = url
  let date1 = Date.now()
  console.log(img.complete)
  while (Date.now() - date1 < 5000) {

  }
  img.onload = function() {
    console.log('success')
  }
  console.log('sync first')
}
loadImg('https://cdn.sstatic.net/Sites/stackoverflow/img/sprites.svg')

Normally, you will get:

false
sync first
success

Well, if you executed on another site which will use cache more than one time. You will get the result like image below:

enter image description here

The answer is clear now.

Well, as long as you set the onload synchronously. You will not miss the onload event.

Why would I say synchronously. For another example,

function loadImg(url) {
  let img = new Image()
  img.src = url
  let date1 = Date.now()
  console.log(img.complete)
  while (Date.now() - date1 < 5000) {
  
   }
  setTimeout(function() {
    img.onload = function() {
      console.log('success')
    }
  })

  console.log('sync first')
}
loadImg('https://cdn.sstatic.net/Sites/stackoverflow/img/sprites.svg')

The result on another site:

enter image description here

The second time with cache, load event won't be triggered. And the reason is setTimeout is asynchronously.

于 2018-06-10T12:04:33.830 回答