首页 文章

在执行某些操作之前,要求jQuery等待所有图像加载的官方方法

提问于
浏览
607

在jQuery中执行此操作时:

$(function() {
   alert("DOM is loaded, but images not necessarily all loaded");
});

它等待DOM加载并执行您的代码 . 如果未加载所有图像,则它仍然执行代码 . 如果我们正在初始化任何DOM内容,例如显示或隐藏元素或附加事件,这显然是我们想要的 .

让我们说虽然我想要一些动画但我不希望它运行直到所有图像都被加载 . jQuery中是否有正式的方法来执行此操作?

我最好的方法是使用 <body onload="finished()"> ,但我不想这样做,除非我必须这样做 .

注意:在Internet Explorer中有bug in jQuery 1.3.1实际上等待所有图像在 $function() { } 中执行代码之前加载 . 所以如果你得到我正在寻找的行为而不是上面描述的正确行为 .

10 回答

  • 48

    使用jQuery,您可以在加载DOM时使用 $(document).ready() 执行某些操作,并在加载所有其他内容时使用 $(window).on("load", handler) 来执行某些操作,例如图像 .

    如果您有一个 jollyroger JPEG文件(或其他合适的文件),可以在以下完整的HTML文件中看到差异:

    <html>
        <head>
            <script src="jquery-1.7.1.js"></script>
            <script type="text/javascript">
                $(document).ready(function() {
                    alert ("done");
                });
            </script>
        </head><body>
            Hello
            <img src="jollyroger00.jpg">
            <img src="jollyroger01.jpg">
            // : 100 copies of this
            <img src="jollyroger99.jpg">
        </body>
    </html>
    

    这样,在加载图像之前会出现警告框,因为此时DOM已准备就绪 . 如果你改变了:

    $(document).ready(function() {
    

    成:

    $(window).on("load", function() {
    

    然后在加载图像之后才会出现警告框 .

    因此,要等到整个页面准备就绪,您可以使用以下内容:

    $(window).on("load", function() {
        // weave your magic here.
    });
    
  • 5

    我写了一个插件,可以在图像加载元素时触发回调,或者每个图像加载时触发一次 .

    它类似于 $(window).load(function() { .. }) ,但它允许您定义要检查的任何选择器 . 如果您只想知道 #content (例如)中的所有图像何时加载,那么这就是您的插件 .

    它还支持加载CSS中引用的图像,例如 background-imagelist-style-image 等 .

    waitForImages jQuery插件

    示例用法

    $('selector').waitForImages(function() {
        alert('All images are loaded.');
    });
    

    Example on jsFiddle .

    GitHub页面上提供了更多文档 .

  • 19

    $(window).load() 仅在第一次加载页面时起作用 . 如果你正在做动态的东西(例如:点击按钮,等待加载一些新图像),这将无法正常工作 . 为此,您可以使用我的插件:

    Demo

    Download

    /**
     *  Plugin which is applied on a list of img objects and calls
     *  the specified callback function, only when all of them are loaded (or errored).
     *  @author:  H. Yankov (hristo.yankov at gmail dot com)
     *  @version: 1.0.0 (Feb/22/2010)
     *  http://yankov.us
     */
    
    (function($) {
    $.fn.batchImageLoad = function(options) {
        var images = $(this);
        var originalTotalImagesCount = images.size();
        var totalImagesCount = originalTotalImagesCount;
        var elementsLoaded = 0;
    
        // Init
        $.fn.batchImageLoad.defaults = {
            loadingCompleteCallback: null, 
            imageLoadedCallback: null
        }
        var opts = $.extend({}, $.fn.batchImageLoad.defaults, options);
    
        // Start
        images.each(function() {
            // The image has already been loaded (cached)
            if ($(this)[0].complete) {
                totalImagesCount--;
                if (opts.imageLoadedCallback) opts.imageLoadedCallback(elementsLoaded, originalTotalImagesCount);
            // The image is loading, so attach the listener
            } else {
                $(this).load(function() {
                    elementsLoaded++;
    
                    if (opts.imageLoadedCallback) opts.imageLoadedCallback(elementsLoaded, originalTotalImagesCount);
    
                    // An image has been loaded
                    if (elementsLoaded >= totalImagesCount)
                        if (opts.loadingCompleteCallback) opts.loadingCompleteCallback();
                });
                $(this).error(function() {
                    elementsLoaded++;
    
                    if (opts.imageLoadedCallback) opts.imageLoadedCallback(elementsLoaded, originalTotalImagesCount);
    
                    // The image has errored
                    if (elementsLoaded >= totalImagesCount)
                        if (opts.loadingCompleteCallback) opts.loadingCompleteCallback();
                });
            }
        });
    
        // There are no unloaded images
        if (totalImagesCount <= 0)
            if (opts.loadingCompleteCallback) opts.loadingCompleteCallback();
    };
    })(jQuery);
    
  • 0

    对于那些希望收到 $(window).load 之后请求的单个图像的下载完成通知的用户,可以使用图像元素的 load 事件 .

    例如 . :

    // create a dialog box with an embedded image
    var $dialog = $("<div><img src='" + img_url + "' /></div>");
    
    // get the image element (as a jQuery object)
    var $imgElement = $dialog.find("img");
    
    // wait for the image to load 
    $imgElement.load(function() {
        alert("The image has loaded; width: " + $imgElement.width() + "px");
    });
    
  • 9

    到目前为止,没有一个答案给出了似乎最简单的解决方案 .

    $('#image_id').load(
      function () {
        //code here
    });
    
  • 1

    我建议使用 imagesLoaded.js javascript库 .

    为什么不使用jQuery的$(window).load()?

    正如https://stackoverflow.com/questions/26927575/why-use-imagesloaded-javascript-library-versus-jquerys-window-load/26929951

    这是一个范围问题 . imagesLoaded允许您定位一组图像,而$(window).load()定位所有资源 - 包括所有图像,对象,.js和.css文件,甚至是iframe . 最有可能的是,imagesLoaded将比$(window).load()更早触发,因为它的目标是一组较小的资产 .

    使用imagesloaded的其他好理由

    • officially supported by IE8+

    • 许可证:MIT许可证

    • 依赖项:无

    • 重量(缩小和压缩):7kb缩小(轻!)

    • 下载构建器(有助于减轻重量):不需要,已经很小了
      在Github上

    • :是的

    • 社区和贡献者:相当大,4000名成员,虽然只有13个贡献者

    • 历史和贡献:相对较老(自2010年以来)稳定但仍然活跃的项目

    资源

  • 997

    随着jQuery我来这个...

    $(function() {
        var $img = $('img'),
            totalImg = $img.length;
    
        var waitImgDone = function() {
            totalImg--;
            if (!totalImg) alert("Images loaded!");
        };
    
        $('img').each(function() {
            $(this)
                .load(waitImgDone)
                .error(waitImgDone);
        });
    });
    

    演示:http://jsfiddle.net/molokoloco/NWjDb/

  • 4

    使用imagesLoaded PACKAGED v3.1.8(最小化时为6.8 Kb) . 它相对较旧(自2010年起)但仍然是活跃的项目 .

    你可以在github上找到它:https://github.com/desandro/imagesloaded

    他们的官方网站:http://imagesloaded.desandro.com/

    为什么它比使用更好:

    $(window).load()
    

    因为您可能想要动态加载图像,如下所示:jsfiddle

    $('#button').click(function(){
        $('#image').attr('src', '...');
    });
    
  • 154

    这样,您可以在加载体内或任何其他容器(取决于您的选择)内的所有图像时执行操作 . PURE JQUERY,无需插件 .

    var counter = 0;
    var size = $('img').length;
    
    $("img").load(function() { // many or just one image(w) inside body or any other container
        counter += 1;
        counter === size && $('body').css('background-color', '#fffaaa'); // any action
    }).each(function() {
      this.complete && $(this).load();        
    });
    
  • 1

    我的解决方案类似于molokoloco . 写成jQuery函数:

    $.fn.waitForImages = function (callback) {
        var $img = $('img', this),
            totalImg = $img.length;
    
        var waitImgLoad = function () {
            totalImg--;
            if (!totalImg) {
                callback();
            }
        };
    
        $img.each(function () {
            if (this.complete) { 
                waitImgLoad();
            }
        })
    
        $img.load(waitImgLoad)
            .error(waitImgLoad);
    };
    

    例:

    <div>
        <img src="img1.png"/>
        <img src="img2.png"/>
    </div>
    <script>
        $('div').waitForImages(function () {
            console.log('img loaded');
        });
    </script>
    

相关问题