【问题标题】:How to fire a callback function after a for-loop is done in Jquery?在Jquery中完成for循环后如何触发回调函数?
【发布时间】:2012-06-15 07:35:21
【问题描述】:

我有两个函数可以计算和调整屏幕上元素的高度和宽度。

panelHeight 将目标元素的高度设置为可用的屏幕高度,而 panelWidth 调整元素的宽度。

我的问题:
我无法确保在第一个函数 (panelHeight) 完成后触发第二个函数 (panelWidth)。如果目标元素很长并且有滚动条,它将被 panelHeight 删除,但如果在 panelWidth 触发之前没有这样做,则设置的宽度将被空格关闭被滚动条占据(17px - 计算宽度时仍然存在)。

所以我正在寻找一种仅在另一个函数完成后才触发函数的方法。有点像回调,但我不确定谁在下面的 for 循环中摆弄这个:

panelHeight: function (from) {
    var self = this,
        o = self.options,
        wrap = $('div:jqmData(wrapper="true").ui-page-active').last(),
        overthrow = wrap.jqmData("scrollmode") == "overthrow" && $('html').hasClass('ui-splitview-mode'),
        blacklist = $('html').hasClass('blacklist'),

        // calculationg toolbars
        // elements
        contents = TARGET_ELEMENT;

    if (overthrow) {
        for ( var i = 0; i < contents.length; i++){
            // calculate values 
            ...
            contents.eq(i).css({    
                        "max-height": setH, 
                        "margin-top": blacklist == true ? glbH + lclH : 0, 
                        "margin-bottom": blacklist == true ? glbF + lclF  : 0
                    })
            }

        } else {

            for ( var i = 0; i < contents.length; i++){
                // calculate values
                ...
                contents.eq(i).css({    
                            "max-height" : "", 
                            "height": o._iPadFixHeight, 
                            "margin-top": blacklist == true ? 
                                parseFloat( lclH.outerHeight() ) : 0, 
                            "margin-bottom": blacklist == true ? 
                                parseFloat( lclF.outerHeight() ) : 0
                        })
                }

            }   
            // USING THIS NOW, WHICH IS NOT NICE                
    window.setTimeout(function(){ self.panelWidth(false ); },65)
    },

所以我要么循环通过 overthrow-if-or-else 循环,只需要触发 panelWidth *AFTER* 循环完成。

问题:
知道如何摆脱超时并将 panelWidth 函数调用添加到循环的末尾吗?我尝试使用 queue,但这也需要 delay(xxx)。我也不能在 for 循环内触发 panelWidth 。我需要它只在高度功能完成后触发一次

编辑
这可能吗:

// calling my panelHeight function like this: 
self.panelHeight("source").done(function() {
   // call panelWidth:
   self.panelWidth();
   });

如果是这样,我应该把 var deferred = Deferred(); 放在哪里?

解决方案
让它工作。谢谢大家!这是我的解决方案:

调用panelHeight时,添加done() handler

$(document).on('pagechange.fixedHeight', function() {
    self.panelHeight("pagechange").done( function() {
        self.panelWidth( false ) 
        });
    });

panelHeight中,声明defer并返回resolved();

panelHeight: function (from) {  
    var deferred = $.Deferred();

    ... run function

    return deferred.resolve();
    }

【问题讨论】:

  • 您的代码中没有异步函数。因此所有代码都是阻塞的,不需要使用回调,只需在代码末尾调用函数即可。如果这不起作用,则问题不在于通话时间,而在于其他问题。

标签: javascript jquery for-loop callback


【解决方案1】:

这就是JQuery Deferred的目的...

var deferred = $.Deferred();

somethingAsync(function() {
    // callback stuff here

    // now tell the deferred task it's ok to proceed
    deferred.resolve();
}

deferred.done(function() {
    // your finalize code here
});

编辑 由于 resolve 事件需要与 dom 调整大小相关联,因此 JavaScript resize 事件处理程序可能会起作用。

【讨论】:

  • 啊。我一直想知道 deferred 是做什么的。所以在回调中我放了我的函数代码并在 deferred.done() 我调用了我的 panelWidth 函数?
  • @frequent 是的,对。我实际上不确定这对你有没有帮助......通常使用 deferred 你会在回调中 resolve ,但在这种情况下没有回调,是吗?
  • 不。上面的函数只是运行,只有在它完成后,我才需要触发另一个函数。现在玩deferred。如果它有效,我会发布
  • 是的,这是正确的用法。查看我的更新,将 resolveresize 事件联系起来可能会起作用。
  • @frequent 没关系,resize 仅适用于 window。看起来您将需要一个 JQuery 插件来检测调整大小事件。 benalman.com/projects/jquery-resize-plugin
猜你喜欢
  • 1970-01-01
  • 2017-07-27
  • 2012-07-01
  • 2012-08-02
  • 1970-01-01
  • 2015-09-12
  • 1970-01-01
  • 1970-01-01
  • 2019-03-25
相关资源
最近更新 更多