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

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

有没有什么好的方法来实现它并实现它,以便它可以在插件中自包含? 我已经尝试循环$('img').complete ,我知道这不起作用(图像永远不会加载,浏览器崩溃,“脚本需要很长时间才能完成”bug)。 有关我正在尝试执行的操作的示例,请访问我要查找的插件页面:

http://www.simplesli.de

如果您转到“更多用途”部分(在导航栏上单击它),您将看到图像幻灯片显示无法正确加载。 我知道当前的代码不起作用,但它只是保持不变,直到我弄明白了。

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

 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').complete是浏览器UI是单线程的,所以你永远不会给它加载图像的机会,因为它总是在你的循环中。 您可以使用setTimeout来允许浏览器工作。 例如,

 $.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 } } }); 

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

 $.ajaxSuccess(function(){ $('img').load(function(){ //Your code here }); }); 

或者当您期待大量图像时:

 $.ajaxSuccess(function(){ $('img:not(.loaded)').addClass('.loaded').bind('load',function(){ //Your code here }); }); 

如果以上任何代码无法正常工作,那么Tou可能希望将代码放入一个回调中,在添加后将html添加到站点。 在上面的函数中使用setTimeout也可能有所帮助。

[编辑]

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

你有没有想过使用live()来绑定所有当前和未来的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 */ }); 

在尝试以几乎所有可以想象的方式完成这项任务之后,这个是最终工作的那个,并且非常感谢Naugtur指出我正确的方向:

 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样式选择器而不是图像Object。它看似完全忽略了(崩溃了页面)。我尝试将Image().onLoad结合使用,并且只要不崩溃页面就可以工作,但它没有执行我编写它的function。

这段代码是自包含的,所以我想它可以复制到任何图像加载应用程序中。 它对我来说似乎足够小,以免侵入。 functionToPerform()基本上充当你想要等待执行的任何函数,直到加载所有图像(在我的情况下,它是整个插件)。 Toodles。