我使用以下Javascript函数来显示图片库。
function disp_pics(currObj,table){
if(currObj != "none"){
$("div .checkout2").removeClass("checkout2").addClass("checkout");
$(currObj).closest("div").removeClass("checkout").addClass("checkout2");
}
function getData(table){
return $.ajax({
url: "newphoto_gallery_display.php",
type: "GET",
data: {
table: table
},
dataType: "html"
});
}
function display_result(data){
var dfd = new $.Deferred();
dfd.done(equalise);
$("#ajaxoutput").html(data);
setTimeout(function() {
dfd.resolve();
}, 1000);
}
function equalise(){
var highestBox = 0;
$('.photodisplay').each(function(){
if($(this).height() > highestBox) {
highestBox = $(this).height();
}
});
$('.photodisplay').height(highestBox);
}
var promise=getData(table);
promise.success(function (data) {
promise.done(display_result(data));
});
};
函数getData从数据库中提取图片数据。函数display_result然后将该数据输出到div id" ajaxoutput"。图片与相关数据一起显示在框中(带边框的HTML表格)。然后调用函数equalize以使所有框具有相同的高度。
如果没有display_result中的时间延迟,则在显示所有图片和数据之前调用均衡功能,从而弄乱显示器。有没有办法消除时间延迟,只有当display_result将所有数据输出到ajaxoutput div时才调用均衡函数?
我已经尝试过各种各样的延期&$。然后.......然后....组合,但是没有设法达到预期的结果而不会延迟脚本,这不是理想的。任何建议都会受到欢迎。
答案 0 :(得分:5)
如果问题是您需要知道您应用于#ajaxoutput
的HTML的所有图像何时被加载(因此浏览器已知其大小),那么您可以这样做监视您添加到HTML的每个图像的onload事件:
function display_result(data){
var dfd = new $.Deferred();
var imgWaiting = 0;
$("#ajaxoutput").html(data).find("img").each(function() {
if (!this.complete) {
// img is still loading, install a load handler so we know when it's done
++imgWaiting;
this.onload = this.onerror = function() {
--imgWaiting;
if (imgWaiting === 0) {
dfd.resolve();
}
}
}
});
if (imgWaiting === 0) {
dfd.resolve();
}
return dfd.promise();
}
然后,你可以这样做:
return getData(table).then(display_result).then(equalise);
这是一个经典的设计模式,承诺用于序列化多个异步操作。
答案 1 :(得分:2)
你需要摆脱超时延迟,因为它不能保证足够长时间才能加载图像(慢速服务器,慢速互联网等)。
不幸的是"正确"您一直在寻找的解决方案并不是最简单的,主要是因为您只能在语句$("#ajaxoutput").html(data)
将它们放置到位后才能访问感兴趣的img节点。在该声明之后的声明中,将不确定(由于浏览器行为)图像是否已经加载(来自缓存)。只需附加一个" onload"处理程序因此不可靠。
解决方法是创建一组屏幕外的img节点,这些节点反映了"#ajaxoutput"和#34; promisify"他们以他们的'src'在附加" onload"之后设置属性。 (和#34; onerror")处理程序。
代码不易遵循,所以我尽力提供解释性评论。
function display_result(data) {
//First a function that creates a promisified <img> node, and returns its promise.
//<img> nodes created here are not appended to the DOM.
function imgPromise(index, imgNode) {
return $.Deferred(function(dfrd) {
//Note the order here - the onload/onerror handler is attached before the src attribute is set.
//Note also that both onload/onerror cause the deferred to be resolved, as you don't want any failures to prevent calling `equalise()`.
$("<img/>").on('load error', dfrd.resolve).attr('src', imgNode.src);
}).promise();
}
//A lot happens in the next line ...
// * "#ajaxoutput" is given some HTML
// * any freshly created image nodes in "#ajaxoutput" are discovered
// * `imgPromise()` is called for each img node in turn and the returned promises are stuffed into an array
// * the array is assigned to local var `promises`.
var promises = $("#ajaxoutput").html(data).find("img").map(imgPromise);
//Finally, `$.when()` returns a promise that is resolved when all `promises` have settled.
//This "summary promise" is returned.
return $.when.apply(null, promises);
}
如果没有评论,你会发现这实际上非常简洁,希望不那么可怕。
function display_result(data) {
function imgPromise(index, imgNode) {
return $.Deferred(function(dfrd) {
$("<img/>").on('load error', dfrd.resolve).attr('src', imgNode.src);
}).promise();
}
var promises = $("#ajaxoutput").html(data).find("img").map(imgPromise);
return $.when.apply(null, promises);
}
请致电如下:
getData(table).then(display_result).then(equalise);
答案 2 :(得分:-1)
你可以同步运行它们吗?
function display_result(data){
$("#ajaxoutput").html(data);
equalise();
}
我非常确定.html函数是一个同步调用,所以你的调整大小将在此之后发生。
已编辑:来自您的ajax调用的数据是什么样的?它只是一堆img标签吗?如果是这样,你可能最好在ajax中加载图像并自己将其编码到html中。