在为图像对象设置src之前是否需要设置onload函数?

时间:2013-02-01 14:33:55

标签: javascript html image

我被告知在为图像对象设置onload之前必须设置src功能。我searched in 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';

必须按此顺序编写?上述代码是否会导致错误(例如图像太大)?

如果你有人能给我看一些例子,我将非常感激。

5 个答案:

答案 0 :(得分:8)

它没有,但如果设置src并且在附加处理程序之前加载图像,则不会触发。

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

答案 1 :(得分:3)

只要为src分配值,图像就会加载。如果在达到onload之前加载,则onload将不会触发。

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

根据我的经验(21年以上的JS),你必须首先设置onload - 尤其是在我开始使用JS时甚至不支持图像对象的IE中。

如果您遇到有关未缓存的缓存图像的问题,请在下次设置src时添加+"?"+new Date().getTime()以避免缓存。

以下是来自MDN的示例,它也使用我建议的顺序

Creating an image from scratch

另一个SO链接image.onload not firing twice in IE7

答案 2 :(得分:2)

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

答案 3 :(得分:2)

如果图像被缓存,大多数浏览器会立即触发加载事件。 但是,Internet Explorer 7根本不会解雇它。这就是为什么最好先设置src的原因。

答案 4 :(得分:0)

上面的答案总是提到同样的问题,如:

  

在附加onload事件处理程序

之前,下载可能已完成

  

但是如果在附加处理程序之前设置src和图像加载,它就不会被激发。

或IE7的错误。

首先,让我们忽略IE7。

其次,我不认为提到的问题存在,例如:



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')
&#13;
&#13;
&#13;

通常情况下,你会得到:

false
sync first
success

好吧,如果您在另一个将使用缓存多次的网站上执行。您将得到如下图所示的结果:

enter image description here

现在答案很清楚。

好吧,只要您同步设置onload即可。您不会错过onload活动。

为什么我会说synchronously。再举一个例子,

&#13;
&#13;
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')
&#13;
&#13;
&#13;

另一个网站的结果:

enter image description here

第二次使用缓存时,load事件不会被触发。原因是setTimeout是异步的。