如何在每次 ajax 调用之前和之后触发某些操作

Posted

技术标签:

【中文标题】如何在每次 ajax 调用之前和之后触发某些操作【英文标题】:How to fire certain action before and after every ajax call 【发布时间】:2011-06-21 08:49:11 【问题描述】:

我正在使用 jQuery 和 jQuery UI。我经历过用户有时会多次触发 ajax 调用,因为触发调用的按钮/链接在点击后并未立即被禁用。为了防止这种情况发生,我现在禁用“beforeSend”-action 中的按钮/链接。

这对我来说是典型的 Ajax 调用:

   $.ajax(
      type: "POST",
      url: "someURL"
      data: "someDataString",
      beforeSend: function(msg)
        $(".button").button("disable");
      ,
      success: function(msg)
        $(".button").button("enable");
        // some user Feedback
      
    );

但我不想在每个 Ajax 调用中添加这个按钮禁用逻辑。有没有办法全局定义一个在 /after 和 ajax-call 之前每次都被调用的函数?

【问题讨论】:

你应该/必须使用哪个版本的 jQuery? 我使用的是最新版本:jQuery 1.5 和 jQueryUI 1.8 我的回答能解决你的问题吗?如果是这样,请接受它:) 【参考方案1】:

有几种方法可以实现您的要求。它们之间的唯一区别是它们的实现方式,您可以选择哪种方法最适合您的特定情况。这些方法还取决于您使用的 jQuery 版本,因此我将把这个答案分成两部分。

对于 jQuery 1.5 及更高版本

在初始化后添加多个回调

从 jQuery 1.5 开始,您可以添加多个回调,这要归功于经过大修的 API 和新引入的由 .ajax 返回的 jqXHR 对象。它实现了 Promise(参见 Deferreds)接口,我们可以利用它来发挥我们的优势:

// fn to handle button-toggling
var toggleButton = function() 
    var button = $(".button");
    button.button(button.button("option", "disabled") ? "enable" : "disable");


// store returned jqXHR object in a var so we can reference to it
var req = $.ajax(
    beforeSend: toggleButton,
    success: function(msg)
        /* Do what you want */
    
).success(toggleButton);

// we can add even more callbacks
req.success(function() ... );

使用预过滤器

jQuery 1.5 还引入了prefilters,您可以使用它来替换 jQuery 1.4 的全局配置:

// good practice: don't repeat yourself, especially selectors
var button = $(".button");

$.ajaxPrefilter(function(options, _, jqXHR) 
    button.button("disable");
    jqXHR.complete(function() 
        button.button("enable");
    );
);

注意:jqXHR section of the $.ajax entry 有关于使用jqXHR.success() 的通知:

弃用通知:jqXHR.success()、jqXHR.error() 和 jqXHR.complete() 回调从 jQuery 1.8 开始被弃用。准备 您最终删除的代码,请使用 jqXHR.done()、jqXHR.fail()、 和 jqXHR.always() 代替。

对于 jQuery 1.4 及更早版本

事件和全局配置

使用.ajaxStart.ajaxStop 将回调绑定到特定的选择器。触发这些回调的事件将在所有 Ajax 请求上触发。

$(".button").ajaxStart(function()
    $(this).button("disable");
).ajaxStop(function()
    $(this).button("enable");
);

使用.ajaxSetup 设置全局ajax 配置。传递给 .ajaxSetup 的设置对象将应用于所有 Ajax 请求,即使是由简写 .get.getJSON.post 发出的请求。请注意,不建议这样做,因为它很容易破坏其功能。

$.ajaxSetup(
    beforeSend: function()
        $(".button").button("disable");
    ,
    success: function()
        $(".button").button("enable");
    
);

过滤掉全局事件回调中的请求

如果您需要过滤掉某些请求,您可以使用.ajaxSend.ajaxComplete 执行此操作,您可以在其中检查 Ajax settings 对象。像这样的:

var button = $(".button");

// fn to handle filtering and button-toggling
var toggleButton = function(settings) 
    if (settings.url == "/specific/url")
        button.button(button.button("option", "disabled") ?
            "enable" : "disable");
    
;

// bind handlers to the callbacks
button.ajaxSend(function(e,x,settings)
    toggleButton(settings);
).ajaxComplete(function(e,x,settings)
    toggleButton(settings);
);

这也可以通过前面提到的.ajaxSetup 对传递给回调处理程序的settings 对象进行相同类型的检查来完成。

【讨论】:

【参考方案2】:

全局注册它们,请使用

ajaxStart 或 ajaxSend 事件

一起

ajaxComplete 或 ajaxStop 事件

$(".button").ajaxStart(function()
      $(this).attr("disabled","disabled");
);


$(".button").ajaxStop(function()
      $(this).attr("disabled","");
);

【讨论】:

【参考方案3】:

是的,您可以通过为每个页面调用此函数来为所有 ajax 调用设置默认值:http://api.jquery.com/jQuery.ajaxSetup/

此外,如果您不想使用默认的 ajax 调用,则只需为该特定 ajax 调用定义该选项。

【讨论】:

【参考方案4】:

您可以尝试将事件处理程序绑定到提交事件,并在每次调用提交操作时调用一个操作。阅读它here。否则AjaxSetup 是另一种好方法。

【讨论】:

以上是关于如何在每次 ajax 调用之前和之后触发某些操作的主要内容,如果未能解决你的问题,请参考以下文章

在Ajax调用之后重新触发Jquery脚本

在调用 f:ajax 侦听器之前和之后执行 JavaScript

jQuery - 在 AJAX 调用之后,旧元素仍然存在于 DOM 中吗?如何去除?

如何使用jquery监控ajax请求的进度响应

按下按钮后和触发 AJAX 调用之前立即显示加载屏幕

thinkjs学习-this.assign传递数据和ajax调用后台接口