【问题标题】:How to delay a function from returning until after clicks have occurred如何延迟函数返回,直到发生点击
【发布时间】:2010-11-05 05:56:19
【问题描述】:

下面的 confirmDialog 函数在另一个 jquery 函数的中途被调用。当此 confirmDialog 返回 true 时,另一个函数应该继续......但它没有。原因似乎是在单击继续按钮时,整个 confirmDialog 函数已经执行(返回 false)。如何延迟它返回任何内容,直到单击按钮之后?

(或者,如果我完全走错了路,问题是什么,我该如何解决?)

function confirmDialog(message) {
....
    $('input#continue', conf_dialog).click(function() {
        $(this).unbind();
        $('p',conf_dialog).fadeOut().text('Are you really sure you want to '+message).fadeIn();
        $(this).click(function() {
            $(conf_dialog).remove();
            return true;
        });
    }); 
    $('input#cancel', conf_dialog).click(function() {
        $(conf_dialog).remove();
        return false;
    }); 
}

【问题讨论】:

    标签: javascript jquery return-value


    【解决方案1】:

    我不确定你能做到。 AFAIK 只有像 confirmalertprompt 这样的内置函数可以在询问答案时阻塞。

    一般的解决方法是重构代码以使用回调(或使用内置函数)。所以这意味着将你的调用函数分成两部分,并在获得输入时执行第二部分。

    【讨论】:

      【解决方案2】:

      您可以在调用下一个函数之前添加超时

      http://www.w3schools.com/htmldom/met_win_settimeout.asp

      【讨论】:

        【解决方案3】:

        在confirmDialog 中,您正在设置事件处理程序,它将在触发事件时执行,而不是在运行confirmDialog 时执行。另一个问题是,您在事件函数内部返回 true 或 false,因此这不适用于外部函数 confirmDialong。

        需要对依赖于按钮按下的部分进行重构。也许把它放在另一个函数中,然后从点击处理程序中调用它:

        var afterConfirm = function(bool) {
            if(bool) {
                //continue clicked
            } else {
                //cancel clicked
            }
            //do for both cases here
        }
        
        //inside confirmDialog input#continue
        $(this).click(function() {
            $(conf_dialog).remove();
            afterConfirm(true);
        });
        

        【讨论】:

          【解决方案4】:
          function callingFunction() {
            $('a').click(function() {
              confirmDialog('are you sure?', dialogConfirmed);
              // the rest of the function is in dialogConfirmed so doesnt 
              // get run unless the confirm button is pressed
            })
          }
          
          function dialogConfirmed() {
            // put the rest of your function here
          }
          
          function confirmDialog(message, callback) {
            ...
            $('input#continue', conf_dialog).click(function() {
              callback()
              $(conf_dialog).remove();
              return false;
            }),
            $('input#cancel', conf_dialog).click(function() {
              $(conf_dialog).remove();
              return false;
            })
            ...
          }
          

          【讨论】:

          • 这几乎是我遵循的方法。我要补充的一件事是,如果您的原始函数接受变量,则必须将这些变量传递给 confirmDialog 函数,然后再传出。
          【解决方案5】:

          您可能想研究使用延迟对象。这里有两个解释它们的链接。

          http://www.sitepen.com/blog/2009/03/31/queued-demystifying-deferreds/

          http://api.dojotoolkit.org/jsdoc/1.3/dojo.Deferred

          使用 Deferred 你可以使用你的调用函数:

          function doSomething () {
            // this functions does something before calling confirmDialog
            if (confirmDialog) {
              // handle ok
            } else {
              // handle cancel
            }
            // just to be difficult lets have more code here
          }
          

          并将其重构为如下内容:

          function doSomethingRefactored() {
            // this functions does something before calling confirmDialog
          
            var handleCancel = function() { /* handle cancel */};
            var handleOk = function() { /* handle ok */};
            var doAfter = function() { /* just to be difficult lets have more code here */};
          
            var d = new dojo.deferred();
            d.addBoth(handleOk, handleCancel);
            d.addCallback(doAfter);
            confirmDialog(message, d);
            return d;
          }
          
          • ConfirmDialog 必须是 更新为调用 d.callback() 或 d.errback() 而不是返回 true 或错误
          • 如果调用的函数 doSomething需要等待 doSomething 完成它可以添加它的 自己的回调链函数

          希望这会有所帮助...阅读 sitepen 文章后会更有意义。

          【讨论】:

            猜你喜欢
            • 2017-10-10
            • 2011-09-14
            • 1970-01-01
            • 2012-07-28
            • 1970-01-01
            • 2020-10-21
            • 2017-08-03
            • 1970-01-01
            • 2021-11-25
            相关资源
            最近更新 更多