jQuery:动态图像处理(等待加载)

jQuery:动态图像处理(等待加载),jquery,image,load,callback,Jquery,Image,Load,Callback,我正在尝试编写一个插件,该插件有一个内置函数,可以等待页面上的所有图像加载后再执行$(window).load()仅当它是页面的初始加载时才起作用,但是如果有人想通过包含图像的AJAX下拉一些HTML,它就不起作用 有没有什么好方法可以做到这一点并实现它,从而使它能够在插件中自包含?我试过在$('img')上循环。完成,我知道这不起作用(图像永远不会加载,浏览器会在“脚本完成时间过长”错误下崩溃)。关于我正在尝试做的一个例子,请访问我正在寻找的用于放置插件的页面: 如果您转到“更多使用”部分(

我正在尝试编写一个插件,该插件有一个内置函数,可以等待页面上的所有图像加载后再执行
$(window).load()
仅当它是页面的初始加载时才起作用,但是如果有人想通过包含图像的AJAX下拉一些HTML,它就不起作用

有没有什么好方法可以做到这一点并实现它,从而使它能够在插件中自包含?我试过在
$('img')上循环。完成
,我知道这不起作用(图像永远不会加载,浏览器会在“脚本完成时间过长”错误下崩溃)。关于我正在尝试做的一个例子,请访问我正在寻找的用于放置插件的页面:

如果您转到“更多使用”部分(在导航栏上单击),您将看到图像幻灯片无法正确加载。我知道当前的代码不起作用,但在我找到答案之前,它只是暂时的

编辑:尝试此解决方案,但不起作用:

if($('.simpleSlide-slide img').size() > 0) {
    var loaded_materials = $('.simpleSlide-slide img').get();
} else {
    var loaded_materials = $('.simpleSlide-slide').get();
}

$(loaded_materials).live('load', function() {
         /* Image processing and loading code */
    });
您是否想过使用绑定到所有当前和未来的
img
元素

$('img').live('load', function ()
{
    alert("image loaded: "+this.src);
});
更新后,我可以看到您遇到的问题
live()
在选择器上效果最好,而在jQuery包装的元素数组上使用它。像这样使用
live()
与使用
bind()
没有什么不同。您应该尝试以下方法:

if($('.simpleSlide-slide img').size() > 0) {
    var loaded_materials = '.simpleSlide-slide img';
} else {
    var loaded_materials = '.simpleSlide-slide';
}

$(loaded_materials).live('load', function() {
         /* Image processing and loading code */
});

我认为您需要将函数绑定到全局ajaxSuccess,然后将加载事件绑定到页面上的每个图像

$.ajaxSuccess(function(){
 $('img').load(function(){
  //Your code here
 });
});
或者当您希望看到大量图像时:

$.ajaxSuccess(function(){
 $('img:not(.loaded)').addClass('.loaded').bind('load',function(){
  //Your code here
 });
});
如果上述任何代码不能正常工作,您可能希望将代码放入回调中,在添加html后将其添加到站点。在上述函数中使用setTimeout可能也会有所帮助

[编辑]


您可以在服务器端代码中生成映像
,并在每个
$.imgHello()
函数调用中增加一些计数器,前提是您知道要加载多少映像。但这并不是我推荐给任何人的解决方案。

在尝试以几乎所有可以想象的方式完成这项任务后,这一项终于奏效了,非常感谢Naugur为我指明了正确的方向:

var no_of_images = $('img').size();

$.extend(no_of_images);

if(no_of_images > 0) {

    var images = new Array();
    var i = 0;
    $('img').each( function() {
        images[i] = $(this).attr('src');
        i++;
    });

    i = 0;

    $(images).each( function(){
        var imageObj = new Image();
        imageObj.src = images[i];
        $(imageObj).load( function() {
            no_of_images--;
            i++;
            if(no_of_images == 0){
                functionToPerform();
            }
        });
    });
} else {
    functionToPerform();
}
为了快速解释发生了什么,我将使用一个类比。想象每一张照片都是你聚会上的一位客人。灯灭了。你打开电灯,然后跑向每位客人,给他们一张纸、一支笔和一部手机,同时统计你向多少人分发了材料。他们都开始疯狂地画画,一旦画完,他们就会打电话告诉你。对于每一个打电话的人,你在黑板上划掉一个计数。当最后一个人打电话给你时(当你的棋盘上没有理货标记时),你告诉他们挂断电话,打电话给披萨店的伙计。比萨饼时间到了。如果一开始没有客人,你就自己给披萨店打电话

如果你在想“为什么他要为每个
$.load()
”创建一个
Image()
对象,那么,我尝试使用传统的jQuery方法,使用一个直接的jQuery样式选择器而不是Image对象。它似乎被完全忽略了(这会使页面崩溃)。我尝试使用
Image()
.onLoad
结合使用,这样做的效果甚至不会使页面崩溃,但它没有执行我编写它的功能


这段代码是自包含的,所以我想它可以复制到任何图像加载应用程序中。对我来说,它似乎足够小,不会造成干扰。
functionToPerform().Toodles.

在图像上循环并调用
$('img')。complete
的问题是浏览器UI是单线程的,因此您永远不会给它加载图像的机会,因为它总是在您的循环中。您可以使用
设置超时
来允许浏览器工作。例如

$.get("whatever",function(html) {
   $('#foo').html(html);
   var images = getTheImages();
   function checkImages() {
      var done = true;
      $.each(images,function() {
         done = done && this.complete;
         return done;
      });
      if(done) {
        fireEvent();
      } else {
        setTimeout(checkImages,100); // wait at least 100 ms and check again
      }
   }
});

我昨晚试过了,但似乎没有效果,除非我完全错过了语法,但对我来说,生活并不是那么复杂。我相信它并不是天生就支持<代码> Load 作为一个事件……你是一个机器!我在打字的时候,我的答案是:P不公平!)@ DCLDO991:文档没有提到。不支持的事件。只需
一个包含JavaScript事件类型的字符串,如“click”或“keydown”“
它甚至声称支持自定义事件,因此我确信它可以支持标准事件:-)@Andy是的,它确实支持所有事件,但只支持最新版本的jquery。它过去只对可用事件的子集起作用,他们必须快速修复它,因为人们不断滥用live()函数。我自己更喜欢跟踪我正在做的事情,如果可能的话,可以使用bind()。请再试一次。好像它不是.live()或其他东西的函数用法。使用Firebug断点,它到达该行,然后进行转储。如果页面上有数百个图像,那么只选择新图像应该比将新加载函数绑定到所有图像更快。但是我会对页面上的图像执行相同的函数吗?这难道不会让一切都慢下来吗?我一直在想,如果有一种方法,我可以让脚本知道页面上有多少个图像(它可以),并且每个图像可以以某种方式通知脚本它的完成,那么脚本可以在完成通知后执行一个函数,那么我就可以开始了。javascript有这样的能力吗?事实上就是这样。但仅适用于单个ajax调用生成的图像。在将图像放到页面上之前,不能将任何内容绑定到事件。你能做的只有一件小事。请看editOops,我认为它不是一个事件处理程序,而是一个内容重写器