【问题标题】:Is it necessary to set onload function before setting src for an image object?是否需要在为图像对象设置 src 之前设置 onload 功能?
【发布时间】:2023-03-13 23:44:01
【问题描述】:

有人告诉我有必要在为图像对象设置src 之前设置onload 函数。为此,我已 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';

必须按这个顺序写?上面的代码是否会导致错误(比如图片太大)?

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

【问题讨论】:

  • 我猜这个是 IE 的错误。

标签: javascript html image


【解决方案1】:

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

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

【讨论】:

  • 脚本执行过程中会发生加载事件吗?请注意,代码示例在设置处理程序和源之间不会返回。
  • 看不清楚,能不能详细解释一下?
  • JavaScript 是异步运行的吗?或者它有时会意外同步运行?正如@JanDvorak 建议的那样,如果您在谈论异步,则期望 onload 将在下一帧上运行,而不是在执行脚本的中间。老实说,我不知道,所以我问,但它似乎如果图像已经加载,某些浏览器可能会触发 onload 同步,因此需要先定义它。
  • 例如this fiddle(显然不是Image.src= 的定义方式,但说明了我的意思),即使onload 立即超时触发,但在定义后仍会触发。
  • 你怎么看这个问题? stackoverflow.com/questions/7552629/…
【解决方案2】:

一旦您为 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

【讨论】:

  • 你怎么看这个问题? stackoverflow.com/questions/7552629/…
  • 我在 JS 方面的多年经验(比图像对象存在的年数还多)必须在设置 src 之前进行加载。在我使用过的所有浏览器中,它都有效。在我使用过的许多浏览器中,它不能反过来工作,直到今天在 Chrome 中我才看到它在你的小提琴中工作
  • 我相信这种方式可以避免很多问题,尽管另一种方式在某些情况下也有效。所以我会接受你的帖子。
  • 我认为答案是,尽管浏览器之间的实现有所不同,但如果您希望其行为一致,您必须首先设置onload
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    如果图像被缓存,大多数浏览器会立即触发加载事件。 但是,Internet Explorer 7 根本不会触发它。所以最好先设置src。

    【讨论】:

    • 我的经验完全没有! - 这个支持我stackoverflow.com/questions/1038327/…
    • 它完全符合我的意思......“这是因为 IE 会缓存图像,并且在加载后永远不会触发 onload 事件。”
    • 并不是说最好先设置src。如果您需要它再次运行,您只需将 src 设置为 + "?"+new Date().getTime() 或类似内容
    【解决方案5】:

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

    有可能在您附加 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')

    通常,您会得到:

    false
    sync first
    success
    

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

    现在答案很清楚了。

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

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

    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')

    另一个网站上的结果:

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

    【讨论】:

      猜你喜欢
      • 2020-11-29
      • 1970-01-01
      • 2012-01-12
      • 2019-07-23
      • 1970-01-01
      • 2013-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多