我不是一个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"
});
有没有人有更好的解决方案?
由于
答案 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);
});
});
由于从未提供完整的代码,假设有多个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秒才能完成:
答案 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。