我正在尝试编写一个内置函数的插件,等待页面上的所有图像在执行之前加载。 $(window).load()
仅在页面的初始加载时才有效,但如果有人想通过包含图像的AJAX下载某些HTML,则它不起作用。
有没有好的方法来实现它并实现它,以便它可以在插件中自包含?我试过循环$('img').complete
,我知道这不起作用(图像永远不会加载,浏览器崩溃,“脚本需要很长时间才能完成”bug)。有关我正在尝试执行的操作的示例,请访问我要查找的插件页面:
如果您转到“更多用途”部分(在导航栏上单击它),您将看到图像幻灯片显示无法正确加载。我知道当前的代码不起作用,但只是在我解决问题之前就一直存在。
编辑:尝试此解决方案,但它不起作用:
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 */
});
答案 0 :(得分:3)
我认为你需要将一个函数绑定到全局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也可能有所帮助。
[编辑]
如果你知道要加载多少个图像,你可以在服务器端代码中生成图像<img src="something" onload="$.imgHello()" />
并在每个$.imgHello()
函数调用中递增一些计数器。但这不是我向任何人推荐的解决方案。
答案 1 :(得分:3)
循环遍历图像并调用$('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
}
}
});
答案 2 :(得分:1)
您是否考虑过使用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 */
});
答案 3 :(得分:1)
在尝试以几乎所有可以想象的方式完成这项任务之后,这个是最终工作的那个,并且非常感谢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();
}
为了快速解释发生了什么,我会用一个类比。想象一下,每个图像都是您聚会的嘉宾。灯灭了。你翻转灯,然后比赛给每个客人,并给他们一张纸,一支笔和一部手机,同时计算你把材料递给了多少人。他们都开始疯狂地画画,然后他们一完成图纸就打电话给你并告诉你。对于每一个打电话的人,你都会从你的董事会中抽出一个记录。当最后一个人打电话给你时(当你的电路板上的计数标记用完时),你告诉他们挂断并打电话给披萨家伙。这是比萨时间。如果没有客人开始,你自己打电话给披萨店。
如果您正在考虑“为什么他为每个Image()
创建一个$.load()
对象,那么,我尝试使用传统的jQuery路由,使用直接的jQuery样式选择器而不是图像对象它似乎完全被忽略了(这使页面崩溃了。)我尝试将Image()
与.onLoad
结合使用,并且只要不崩溃页面就可以工作,但它没有执行其中的功能我写了。
这段代码是自包含的,所以我想它可以被复制到任何图像加载应用程序中。这对我来说似乎足够小,以免侵入。 functionToPerform()
基本上充当您想要等待执行的任何函数,直到加载所有图像(在我的情况下,它是整个插件)。 Toodles。