jQuery Ajax 等待所有图像加载完毕

发布于 2024-10-13 12:44:31 字数 400 浏览 4 评论 0原文

我正在尝试使用 jQuery 执行 Ajax 调用,效果很好。我使用成功事件来显示数据。然而,一旦加载外部 HTML 文件,似乎就会触发成功。如果有大图像,它们在显示后会继续加载。有没有办法在全部加载完毕后显示内容?这是代码:

$('#divajax').html('<br><div style="text-align: center;"><img src="res/ajax-loader.gif"></div>');
$.ajax({
    cache: false,
    url: 'ajax/content.php',
    success: function(data) {
          $('#divajax').html(data);
    }
});

I'm trying to perform an Ajax call with jQuery which is working well. I use the success event to display the data. It seems however that success gets triggered as soon as the external HTML file gets loaded. If there are large images they keep loading after they're shown. Is there a way to display the content after everything is fully loaded? Here is the code:

$('#divajax').html('<br><div style="text-align: center;"><img src="res/ajax-loader.gif"></div>');
$.ajax({
    cache: false,
    url: 'ajax/content.php',
    success: function(data) {
          $('#divajax').html(data);
    }
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

未央 2024-10-20 12:44:31

@alex 编写的插件由于某种原因对我不起作用......我不明白为什么。但他的代码确实激发了我想出一个更适合我的轻量级解决方案。它使用 jquery 承诺。请注意,与 @alex 的插件不同,这不会尝试考虑元素上的背景图像,而仅考虑 img 元素。

// Fn to allow an event to fire after all images are loaded
$.fn.imagesLoaded = function () {

    // get all the images (excluding those with no src attribute)
    var $imgs = this.find('img[src!=""]');
    // if there's no images, just return an already resolved promise
    if (!$imgs.length) {return $.Deferred().resolve().promise();}

    // for each image, add a deferred object to the array which resolves when the image is loaded (or if loading fails)
    var dfds = [];  
    $imgs.each(function(){

        var dfd = $.Deferred();
        dfds.push(dfd);
        var img = new Image();
        img.onload = function(){dfd.resolve();}
        img.onerror = function(){dfd.resolve();}
        img.src = this.src;

    });

    // return a master promise object which will resolve when all the deferred objects have resolved
    // IE - when all the images are loaded
    return $.when.apply($,dfds);

}

然后你可以像这样使用它:

$.ajax({
    cache: false,
    url: 'ajax/content.php',
    success: function(data) {
        $('#divajax').html(data).imagesLoaded().then(function(){
            // do stuff after images are loaded here
        });
    }
});

希望这对某人有帮助。

请注意,使用上述代码时,如果其中一张图像出现错误(例如,因为 URL 错误),则无论如何都会解决 Promise 并忽略该错误。这可能是您想要的,但是,根据您的情况,如果图像加载失败,您可能想中止正在执行的任何操作。在这种情况下,您可以按如下方式替换 onerror 行:

img.onerror = function(){dfd.reject();}

并捕获如下错误:

$('#divajax').html(data).imagesLoaded().done(function(){
    // do stuff after all images are loaded successfully here
}).fail(function(){
    // do stuff if any one of the images fails to load
});

The plugin that @alex wrote didn't work for me for some reason... I couldn't figure out why. But his code did inspire me to come up with a more lightweight solution that is working for me. It uses jquery promises. Please note that unlike @alex 's plugin, this doesn't attempt to account for background images on elements, only img elements.

// Fn to allow an event to fire after all images are loaded
$.fn.imagesLoaded = function () {

    // get all the images (excluding those with no src attribute)
    var $imgs = this.find('img[src!=""]');
    // if there's no images, just return an already resolved promise
    if (!$imgs.length) {return $.Deferred().resolve().promise();}

    // for each image, add a deferred object to the array which resolves when the image is loaded (or if loading fails)
    var dfds = [];  
    $imgs.each(function(){

        var dfd = $.Deferred();
        dfds.push(dfd);
        var img = new Image();
        img.onload = function(){dfd.resolve();}
        img.onerror = function(){dfd.resolve();}
        img.src = this.src;

    });

    // return a master promise object which will resolve when all the deferred objects have resolved
    // IE - when all the images are loaded
    return $.when.apply($,dfds);

}

Then you can use it something like this:

$.ajax({
    cache: false,
    url: 'ajax/content.php',
    success: function(data) {
        $('#divajax').html(data).imagesLoaded().then(function(){
            // do stuff after images are loaded here
        });
    }
});

Hopefully that's helpful for someone.

Note that using the above code, if one of the images errors (eg because the URL was wrong), the promise is resolved anyway and the error is ignored. This might be what you want, but, depending on your situation, you might instead want to abort whatever you are doing if an image fails to load. In which case you could replace the onerror line as follows:

img.onerror = function(){dfd.reject();}

And catch the error like this:

$('#divajax').html(data).imagesLoaded().done(function(){
    // do stuff after all images are loaded successfully here
}).fail(function(){
    // do stuff if any one of the images fails to load
});
汹涌人海 2024-10-20 12:44:31

您可以使用我的 jQuery 插件 waitForImages...

$.ajax({
    cache: false,
    url: 'ajax/content.php',
    success: function(data) {

         $('#divajax').html(data).hide().waitForImages(function() {
             $(this).show();
         });

    }
});

这会将内容加载到您的元素中,隐藏它,然后重新显示一次后代 img 元素已加载。

You could use my jQuery plugin, waitForImages...

$.ajax({
    cache: false,
    url: 'ajax/content.php',
    success: function(data) {

         $('#divajax').html(data).hide().waitForImages(function() {
             $(this).show();
         });

    }
});

This will load the stuff into your element, hide it, and then reshow it once descendent img elements have loaded.

山田美奈子 2024-10-20 12:44:31

您可以将某些内容绑定到加载事件以了解它们何时完成:

$('<img>').bind('load', function() {
    $(this).appendTo('body');
});

或者您可以使用此插件

You can bind something to the load events to know when they're done:

$('<img>').bind('load', function() {
    $(this).appendTo('body');
});

Or you could use this plugin.

独行侠 2024-10-20 12:44:31

这会在每个 img 加载上分别触发:

$('img').on('load', function() {
      // do something
});

我使用:

var loaded = 0;
$('img').on('load', function() {
   loaded++;
   if(loaded == $('img').length){
      // do something
   }
});

this triggers on every img load separately:

$('img').on('load', function() {
      // do something
});

i used:

var loaded = 0;
$('img').on('load', function() {
   loaded++;
   if(loaded == $('img').length){
      // do something
   }
});
浅唱々樱花落 2024-10-20 12:44:31

您可以使用 imagesloaded 插件JavaScript 和 jQuery,尝试在加载的内容上使用内部 ajax success 回调函数,并在 imagesloaded 回调函数不触发时隐藏所有内容,请参见下面的示例代码

$.ajax({
    cache: false,
    url: 'ajax/content.php',
    success: function(data) {
        var $divajax = $('#divajax').html(data).hide();
        $divajax.imagesLoaded(function() {
             $divajax.show();
         });

    }
});

You can use imagesloaded plugin that is work with JavaScript and jQuery, try to use inside ajax success callback function on loaded content, and hide all content while imagesloaded callback function not trigger, see below sample code

$.ajax({
    cache: false,
    url: 'ajax/content.php',
    success: function(data) {
        var $divajax = $('#divajax').html(data).hide();
        $divajax.imagesLoaded(function() {
             $divajax.show();
         });

    }
});
情绪少女 2024-10-20 12:44:31

考虑使用 jquery 的 .load() ,

其中有以下描述:

当元素和所有子元素完全加载时,将向该元素发送加载事件。此事件可以发送到与 URL 关联的任何元素:图像、脚本、框架、iframe 和窗口对象。

Look into using jquery's .load()

Which has a description of :

The load event is sent to an element when it and all sub-elements have been completely loaded. This event can be sent to any element associated with a URL: images, scripts, frames, iframes, and the window object.

不再让梦枯萎 2024-10-20 12:44:31
$('#divajax').html('<br><div style="text-align: center;"><img src="res/ajax-loader.gif"></div>').load(function() {
$.ajax({
    cache: false,
    url: 'ajax/content.php',
    success: function(data) {
          $('#divajax').html(data);
    }
});
});
$('#divajax').html('<br><div style="text-align: center;"><img src="res/ajax-loader.gif"></div>').load(function() {
$.ajax({
    cache: false,
    url: 'ajax/content.php',
    success: function(data) {
          $('#divajax').html(data);
    }
});
});
零崎曲识 2024-10-20 12:44:31

试试这个代码。效果很好。

$.ajax({
    url: "../api/listings",
    type: 'GET',
    success: function (html) {
        $('#container').append(html);
        $('#container img').on('load', function(){console.log('images loaded')});
    };
});

Try this code. It works fine.

$.ajax({
    url: "../api/listings",
    type: 'GET',
    success: function (html) {
        $('#container').append(html);
        $('#container img').on('load', function(){console.log('images loaded')});
    };
});
找个人就嫁了吧 2024-10-20 12:44:31

当丹尼尔的解决方案中的插件找不到图像时,我遇到了一个小错误。

以防万一其他人遇到同样的问题:

更改:

// if there's no images, just return an already resolved promise
if (!$imgs.length) {return $.Deferred.resolve().promise();}

到:

// if there's no images, just return an already resolved promise
    if (!$imgs.length) {
        var dfd = $.Deferred();
        return dfd.resolve().promise();
    }

I've got a small bug when no images are found by the plugin from Daniel's solution.

Just in case some else get the same issue:

Change:

// if there's no images, just return an already resolved promise
if (!$imgs.length) {return $.Deferred.resolve().promise();}

To :

// if there's no images, just return an already resolved promise
    if (!$imgs.length) {
        var dfd = $.Deferred();
        return dfd.resolve().promise();
    }
红颜悴 2024-10-20 12:44:31

我认为最好的就是使用这个

$(window).ready(function(){ //load your ajax})

i think the best is using this

$(window).ready(function(){ //load your ajax})
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文