我不是一个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"
});
Run Code Online (Sandbox Code Playgroud)
有没有人有更好的解决方案?
谢谢
Gon*_*ing 12
假设每次单击都触发了一个Ajax调用(你为什么会遇到这个问题),你可以简单地等待任何/所有Ajax请求完成:
$(document).ajaxStop(function () {
window.location.href = "<?php echo $base_url ?>/sign/print"
});
Run Code Online (Sandbox Code Playgroud)
如果需要,您还可以在更改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);
});
});
Run Code Online (Sandbox Code Playgroud)
由于从未提供完整的代码,假设有多个ajax调用,解决方案就是猜测.
一般的解决方案是不触发点击事件,而是以承诺友好的方式简单地为每次点击调用相关代码.
假设每个单击处理程序都有一个专用函数,只需让每个函数返回一个promise:
例如
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();
}
Run Code Online (Sandbox Code Playgroud)
然后在你的例子中使用它(顺序运行.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"
});
});
Run Code Online (Sandbox Code Playgroud)
或者,如果它们可以并行运行,请使用$.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"
});
});
Run Code Online (Sandbox Code Playgroud)
只是为了正确起见,这可以通过jQuery Deferreds以干净的异步方式完成.这些对象代表将来完成的任务,事件处理程序可以附加到它的完成.您可以手动延迟调用完成.
对于具有回调的大多数异步任务,这些对象是jQuery在幕后使用的对象,您实际上可以等待它们完成.
您需要稍微更改一下代码.
在click eventhandler中#printpng,您需要为要完成的每个任务创建延迟对象.
假设你手动触发的所有3个点击事件都需要等待,所以我们创建3个延迟.
$('#printpng').click(function () {
var def1 = $.Deferred();
var def2 = $.Deferred();
var def3 = $.Deferred();
.......... other code not yet included
});
Run Code Online (Sandbox Code Playgroud)
现在我们有3个代表任务的对象.如果你打电话.resolve()给他们,这意味着任务完成.我们希望在#tool_export点击事件处理程序完成后完成这些任务.
假设这#tool_export有一个click事件处理程序,我们以某种方式能够将延迟对象传递给它.
$('#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();
}
},
});
});
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它会进行AJAX调用,deferred.resolve()如果调用成功并且出现问题deferred.reject()则会调用.非常简单.
现在的问题是:如何将此延迟参数传递给click事件处理程序?
你写:
$('#tool_docprops').click();
Run Code Online (Sandbox Code Playgroud)
这是一个简写:
$('#tool_docprops').trigger('click');
Run Code Online (Sandbox Code Playgroud)
要将def1对象作为参数传递,您只需编写:
$('#tool_docprops').trigger('click', def1);
Run Code Online (Sandbox Code Playgroud)
所以你的事件处理程序被修改为:
$('#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
});
Run Code Online (Sandbox Code Playgroud)
您可以根据需要传递任意数量的参数.
最后要做的是总结这个延迟.有一个非常酷的辅助方法.when(),它等待解决任意数量的延迟.由于它也会创建延迟,因此您可以调用deferred.done()它来获取回调.所以要等待你之前创建的所有3个延迟,你可以写:
$.when(def1, def2, def3).done(function() {
window.location.href = "<?php echo $base_url ?>/sign/print";
});
Run Code Online (Sandbox Code Playgroud)
所以你的最终点击事件处理程序#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";
});
});
Run Code Online (Sandbox Code Playgroud)
我做了一个非常简单的例子来说明这一点.没有ajax调用只有超时,但你可以得到这个想法.
如果单击start,则需要等待4秒才能完成: