【问题标题】:jquery: how to listen to the image loaded event of one container div?jquery:如何监听一个容器 div 的图像加载事件?
【发布时间】:2011-12-20 02:14:00
【问题描述】:

我有一个容器,里面有一些图像,我想监听每个图像完成加载的事件。

例如)

<div id="container">
     <img src="..." />
     <img src="..." />
     <img src="..." />
     <img src="..." />
</div>

我应该得到 4 次“图像加载”事件。 如何做到这一点?

【问题讨论】:

    标签: javascript jquery html


    【解决方案1】:

    侦听 HTML 源中图像加载事件的唯一可靠方法是在 HTML 中指定 onload 处理程序:

    <div id="container">
         <img onload="imageLoad()" src="..." />
         <img onload="imageLoad()" src="..." />
         <img onload="imageLoad()" src="..." />
         <img onload="imageLoad()" src="..." />
    </div>
    

    这是因为在图像标签自己加载(因此它们存在于 DOM 中)之前,您无法将事件处理程序附加到页面 HTML 中的图像。一旦加载了这些图像标签,图像的源就已经被加载,如果它可以快速使用(比如在浏览器缓存中),它可能会在您附加事件处理程序之前被加载。因此,充其量你不能确定它会起作用,最坏的情况是它不会起作用。无论如何,它可能不可靠。

    或者,如果您只想知道页面中的所有图像何时加载,您可以对整个文档使用 load 事件。在 jQuery 中,您可以使用 $(window).load(fn) 来做到这一点。

    或者,您可以附加加载事件,然后检查是否有任何图像已加载并将其计为已加载。我不确定是否有官方标准方法来查看图像是否已经加载,但我发现如果在 HTML 中没有设置宽度并且.width 属性有一个非零值,则必须加载图像,因为加载图像会导致设置非零宽度值。

    您的另一个选择是不将图像放入页面的 HTML 并动态添加它们,您可以在创建图像时分配负载处理程序,然后再分配 .src 属性。


    测试问题

    为了进一步探索这一点,我在 jsFiddle 中构建了一个测试平台:http://jsfiddle.net/jfriend00/7FjdJ/。它有四个图像,并报告在 $(document).ready() 触发时已经加载了多少图像,并报告有多少图像触发了.load() 事件。结果显示了从一个浏览器到另一个浏览器的行为变化。

    在 Chrome 15 中,如果图像已经在缓存中,我不会收到任何加载事件,并且当$(document).ready() 触发时所有四个都已经加载。该行为似乎会根据图像之后页面中的内容量而有所不同。

    在 Safari 5 中,我第一次加载页面时,它会报告 4 个加载事件,0 个图像已经加载。我第二次加载页面时,它报告了 0 个加载事件,已经加载了 4 个图像。

    在 IE9 中,图像总是看起来已经加载,并且无论是否缓存,都不会触发加载事件。

    在 Firefox 7 中,第一次加载页面时,我得到 0 个加载事件和 4 个已经加载的图像。下次我加载页面时,我得到了 4 个加载事件和 4 个已经加载的图像。

    另外,由于这是一个时间问题,如果行为取决于图像的大小和加载它们的速度,我也不会感到惊讶,因为缓慢的加载图像可能会导致加载事件延迟到足以被看到。它还可能取决于图像之后页面中要加载多少内容(例如,在触发 document.ready 之前要完成多少工作)。

    所以,我的结论是,在图像开始加载后安装 .load() 事件处理程序的行为从一个浏览器到下一个浏览器以及从一种情况到另一种情况是不一致的,因此你不能指望它没有其他缓解这些差异的代码(检查图像是否已加载)。


    还有另一种方法。您可以在 DOM 加载后安装事件处理程序,并且在安装事件处理程序时,您可以检查图像是否已加载。这是一种方法:

    <div id="container">
         <img src="..." />
         <img src="..." />
         <img src="..." />
         <img src="..." />
    </div>
    
    <script>
    $("#container img").each(function() {
        if (this.complete) {
            // this image already loaded
            // do whatever you would do when it was loaded
        } else {
            $(this).on('load', function() {
                // image now loaded
            });
        }
    }); 
    

    工作演示:http://jsfiddle.net/jfriend00/6Cq4y/

    你会在演示中发现,如果你的浏览器缓存从未见过这个 jsFiddle,那么 if 会显示 4 个加载事件,但如果浏览器缓存已经见过这个 jsFiddle,那么它将没有任何加载事件和所有图像将在您的 javascript 运行时加载,并且会看到它们已加载到代码的 if (this.complete) 分支中。

    【讨论】:

    • 添加了第二种方法来检查 this.complete 并且不需要将 onload 处理程序放入 HTML。
    【解决方案2】:

    使用 jQuery:

    $('#container img').load(function() {
        alert('image loaded');
    });
    

    使用简单的 javascript 你可以使用onload 属性:

    <img src="yourimage.gif" onload="loadImage()" />
    

    函数将是:

    function loadImage() {
        alert("image loaded");
    }
    

    【讨论】:

    • 这个答案和我的几乎相同,这有点好笑,但我的却被否决了 :-)
    • 让我生气你以为我投了反对票……和 jfriend00 谈谈,他对此有点挑剔。我们在您的回答中进行了讨论...
    • ??我不知道是谁对我投了反对票……我当然不是故意责怪你的!
    【解决方案3】:
    $('#container img').load(function() {
      // ...
    });
    

    您需要将其设置为非常接近将元素引入 DOM 的位置,否则可能会在您设法附加事件处理程序之前加载它们。

    【讨论】:

    • 这不能保证是可靠的,因为来自缓存的图像可以很容易地加载,然后才能运行此 javascript。
    • @jfriend00 他不是在说动态加载图片,只是在监听 onload image 的事件
    • @Nacho - 在我看来,他想知道页面 HTML 中的图像何时加载。在 DOM 加载后安装事件处理程序不能可靠地做到这一点。您必须在 HTML 中或在设置 .src 之前安装事件处理程序。如果图像在页面 HTML 中,那么您也必须将事件处理程序放在 HTML 中。
    • @jfriend00 好吧,你是对的,但我假设他在 head 元素中使用该脚本,但我可能假设太多:S
    • @Nacho - 你不能在 HEAD 元素中运行它。 DOM 对象还没有安装事件处理程序。
    猜你喜欢
    • 2018-12-27
    • 1970-01-01
    • 2014-08-31
    • 2022-12-19
    • 2014-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-11
    相关资源
    最近更新 更多