点击事件的JQuery .done

时间:2014-01-10 09:36:58

标签: javascript jquery

我不是一个javascript开发人员,所以请耐心等待......

我需要在jQuery click事件完成后执行重定向。这就是我所拥有的,但我无法将.done应用于.click。在$.when中包装整个内容并不起作用......

$("#printpng").click(function(){
            $('#tool_docprops').click();
            $('#tool_docprops_save').click();
            $('#tool_export').click()
        }).done(function(){
                window.location.href = "<?php echo $base_url ?>/sign/print"
        });

有没有人有更好的解决方案?

由于

5 个答案:

答案 0 :(得分:12)

假设每次点击都会触发您的控制中的Ajax调用(否则为什么会出现此问题),您可以简单地等待任何/所有Ajax请求完成:

$(document).ajaxStop(function () {
     window.location.href = "<?php echo $base_url ?>/sign/print"
  });

如果需要,您还可以在更改URL之前添加超时,以防在Ajax加载后进行其他处理。 如果它不是Ajax问题,请澄清,我将调整(或删除)这个答案。

完整版(Ajax等待后额外延迟1秒)可能如下所示:

$("#printpng").click(function(){
    $('#tool_docprops').click();
    $('#tool_docprops_save').click();
    $('#tool_export').click();
    $(document).ajaxStop(function () {
        setTimeout(function(){
             window.location.href = "<?php echo $base_url ?>/sign/print"
        }, 1000);
    });
});

正如所承诺的[原文如此]使用 promises

的更好的解决方案

由于从未提供完整的代码,假设有多个ajax调用,解决方案就是猜测。

一般的解决方案是不会触发点击事件,而是以承诺友好的方式简单地为每次点击调用相关代码。

假设每个click处理程序都有一个专用函数,只需让每个函数返回一个promise:

e.g。

 function loadPropsViaAjax(){
     // simply return the ajax call as $.ajax returns a promise
     return $.ajax({parameters here});
 }

 function saveDocPropsViaAjax(){
     // simply return the ajax call as $.ajax returns a promise
     return $.ajax({parameters here});
 }

 function waitForImageToload(){
     // create a deferred object
     var def = $.Deferred();

     // When the image eventually loads, resolve the promise
     $('#someimageselector').on('load', function(){
        def.resolve();
     });

     // Return the promise immediately
     return def.promise();
 }

然后在你的例子中使用它(使用.then()顺序运行):

 // On click button event...
 $("#printpng").click(function(){
    // Run operations sequentially
    loadPropsViaAjax().then(saveDocPropsViaAjax).then(waitForImageToload)
        .done(function(){
            window.location.href = "<?php echo $base_url ?>/sign/print"
     });
 });

或者如果它们可以并行运行,请使用$.when

 // On click button event...
 $("#printpng").click(function(){
    // Run operations in parallel
    $.when(loadPropsViaAjax, saveDocPropsViaAjax, waitForImageToload)
        .done(function(){
            window.location.href = "<?php echo $base_url ?>/sign/print"
     });
 });

答案 1 :(得分:6)

为了正确起见,可以使用jQuery Deferreds以干净的异步方式完成此操作。这些对象代表将来完成的任务,事件处理程序可以附加到它的完成。您可以手动延迟调用完成。

这些对象是jQuery在幕后工作的大多数具有回调功能的异步任务,您实际上可以等待它们完成。

您需要稍微更改一下代码。

#printpng的click事件处理程序中,您需要为要完成的每个任务创建延迟对象。

让我们说你手动触发的所有3个点击事件都需要等待,所以我们创建3个延迟。

$('#printpng').click(function () {
    var def1 = $.Deferred();
    var def2 = $.Deferred();
    var def3 = $.Deferred();

    .......... other code not yet included
});

现在我们有3个代表任务的对象。如果您对它们调用.resolve(),则表示任务已完成。我们希望在#tool_export点击事件处理程序完成后完成这些任务。

让我们说这个#tool_export有一个点击事件处理程序,我们能够以某种方式将延迟对象传递给它。

$('#tool_export').click(function (e, deferred) {
    $.ajax({
        url: 'your_url',
        success: function(result){

            // your code does stuff with the result

            if (deferred !== undefined) {
                deferred.resolve();
            }
        },
        error: function(result){
            if (deferred !== undefined) {
                deferred.reject();
            }
        },
    });
});

正如您所看到的,它会进行AJAX调用,如果调用成功则调用deferred.resolve(),如果出现问题则调用deferred.reject()。非常简单。

现在问题是:如何将此延迟参数传递给click事件处理程序?

你写过:

$('#tool_docprops').click();

以下是:

的简写
$('#tool_docprops').trigger('click');

要将def1对象作为参数传递,您只需编写:

$('#tool_docprops').trigger('click', def1);

所以你的事件处理程序被修改为:

$('#printpng').click(function () {
    var def1 = $.Deferred();
    var def2 = $.Deferred();
    var def3 = $.Deferred();

    $('#tool_docprops').trigger('click', def1);
    $('#tool_docprops_save').trigger('click', def2);
    $('#tool_export').trigger('click', def3);

    ..... something is still missing from here
});

您可以根据需要传递任意数量的参数。

要做的最后一件事就是完成这个延迟的总结。有一个很酷的辅助方法叫做.when(),它等待解决任意数量的延迟。由于它也会创建延迟,因此您可以在其上调用deferred.done()以获得回调。因此,要等待您之前创建的所有3个延迟,您可以写:

$.when(def1, def2, def3).done(function() { 
    window.location.href = "<?php echo $base_url ?>/sign/print";
});

所以#printpng的最终点击事件处理程序将是:

$('#printpng').click(function () {
    var def1 = $.Deferred();
    var def2 = $.Deferred();
    var def3 = $.Deferred();

    $('#tool_docprops').trigger('click', def1);
    $('#tool_docprops_save').trigger('click', def2);
    $('#tool_export').trigger('click', def3);

    $.when(def1, def2, def3).done(function() { 
        window.location.href = "<?php echo $base_url ?>/sign/print";
    });
});

我做了一个非常简单的例子来说明这一点。没有ajax调用只有超时,但你可以得到这个想法。

如果单击“开始”,则需要等待4秒才能完成:

http://jsfiddle.net/3ZDEe/2/

答案 2 :(得分:-1)

尝试这样的事情

$("#printpng").click(function(){
    $('#tool_docprops').click();
    $('#tool_docprops_save').click();
    $('#tool_export').click()
    window.location.href = "<?php echo $base_url ?>/sign/print"
});

尝试制作async = false

$.ajax({
    url:"demo_test.txt",
    async: false,
    success:function(result){
        $("#div1").html(result);
    }
});

答案 3 :(得分:-1)

据我所知,你需要在点击事件完成后执行页面重定向。 为此,您只需在click事件上添加一个回调函数。

单击完成后,此回调函数会触发,并在此函数中编写重定向代码。

例如:

$("#printpng").click(function(){
   $('#tool_docprops').click(function(e){
      // write here your redirection code
   });
   $('#tool_docprops_save').click(function(e){
     // write here your redirection code
   });
   $('#tool_export').click(function(e){ 
     // write here your redirection code
   });
});

感谢

答案 4 :(得分:-2)

只需在点击处理程序的末尾编写重定向代码。

$("#printpng").click(function(){
    $('#tool_docprops').click();
    $('#tool_docprops_save').click();
    $('#tool_export').click();
    window.location.href = "<?php echo $base_url ?>/sign/print";
});

如果在更新页面位置之前需要等待异步进程(由点击事件触发)完成,则需要修复解决方案。

即。您的异步进程是一个ajax调用,它在单击#tool_docprops_save后生成一个请求。你应该在ajax-call上附加一个成功事件,它将在ajax-call完成后更新window.location.href。