Javascript/JQuery - 如何在完成前一个函数时调用一个函数

标签 javascript jquery deferred

我正在使用以下 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 时才调用 equalize 函数?

我已经尝试了各种 Deferred 和 $.when......then.... 的组合,但没有在不延迟脚本的情况下实现预期的结果,这并不理想。欢迎提出任何建议。

最佳答案

如果问题是您需要知道您应用到 #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);

这是一个经典的设计模式, promise 序列化多个异步操作。

关于Javascript/JQuery - 如何在完成前一个函数时调用一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27512548/

相关文章:

javascript - 使用 style.position 定位对象

javascript - jQuery Deferred/Promises 与许多 getJSON

javascript - jQuery 延迟 : create a chain sequence using conditions

python - 扭曲的,延迟的完整回溯

javascript - 使用 iPad 或其他移动设备时出现不需要的鼠标悬停效果

javascript - KonvaJs:为箭头添加边框

javascript - 如何正确使用 for 循环在按钮数组中添加 onclick 函数?

c# - 海量数据的 asp.net 下拉列表缓存

javascript - jQuery - 选择子 div 背景图像并修改它

javascript - 使用 Javascript 将带有 mySql 数据库的 php 文件转换为 html