【问题标题】:Disabling some jQuery global Ajax event handlers for a request为请求禁用一些 jQuery 全局 Ajax 事件处理程序
【发布时间】:2011-11-18 04:03:22
【问题描述】:

假设我定义了一些全局 Ajax 事件处理程序(ajaxStart、ajaxStop 和 ajaxError)。通常我对此很好,但是对于一个请求,我想禁用 ajaxError 处理程序,但仍像往常一样运行 ajaxStart 和 ajaxStop 处理程序。 jQuery ajax function documentation 提到了可以设置为 false 并传递给 $.ajax 函数以禁用所有全局 Ajax 事件处理程序的“全局”参数,但它们没有提到仅禁用某些全局处理程序的任何方法。

我可以通过对传递给 ajaxError 函数的 ajaxSettings 对象的“url”属性进行测试来阻止 ajaxError 处理程序,但这似乎有些笨拙。这里有没有人知道禁用 ajaxError 函数运行的方法,这对看起来很清楚的人来说是 在调用 $.ajax 函数的地方?

如果有人想看,我可以提供一个简单的例子。

【问题讨论】:

  • 您是否尝试过(我猜这个)将您自己的.error 处理程序添加到$.ajax() 调用中,然后将return false 放在函数末尾以停止处理?
  • 是的,我试过了。它没有解决问题。全局处理程序仍在运行。
  • 如果我没记错的话,全局处理程序(成功、错误、完成)在成功/错误/完成处理程序之前运行。

标签: javascript jquery ajax


【解决方案1】:

这是可能的,而且不难做到。

您只需要设置全局错误处理程序 (.ajaxError) 即可接收 jQuery 可以提供给它的一些参数:

$("div.log").ajaxError(function(evt, xhr, settings) {
    if(settings.suppressErrors) {
        return;
    }

    // Normal processing
});

在此之后,您可以将suppressErrors: true 添加到您发出的任何 AJAX 请求的设置中,如果失败,错误处理程序将返回而不执行通常的操作。

See it in action。

【讨论】:

  • 这看起来是迄今为止最好的答案。我喜欢你的例子。
  • 我试过你的想法,它奏效了。我可能会将赏金奖励给你,除非其他人能想出更优雅的解决方案。
  • 将字段添加到我们实际上并不拥有的对象似乎... icky。
  • @JimmyBreck-McKye:我完全理解你的不安,但 options 对象的使用方式与此完全相同——参见例如api.jquery.com/jquery.ajaxprefilter 的示例
  • @Jon - 很公平 - 如果文档给出了我们以这种方式使用对象的示例,似乎我们应该能够依赖它。不过,我可能仍然想在我的字段名称前加上前缀,以避免有一天发生命名冲突的可能性。
【解决方案2】:

当您查看来自 jquery/ajax 源 https://github.com/jquery/jquery/blob/master/src/ajax.js#L579-582 的 if 语句时,它是许多同类中的一个,很明显您的问题不能仅通过 jquery 参数来解决。

我的建议是:

  • 将 global 设置为 false,就像 Vaibhav Gupta 所说的那样

  • 在特定的 ajax 调用中将全局处理程序映射到本地,并通过 $.event.trigger 方法触发全局事件

示例:

$.ajax({
    url: "test.html",
    global: false,
    beforeSend: function(){$.event.trigger('ajaxStart');},
    complete: function(){$.event.trigger('ajaxStop');},
    error: your_error_handler
});

【讨论】:

  • 这看起来可能会阻止错误处理程序,但它可能会导致其他微妙的问题。 beforeSend 处理程序只应该在第一个 Ajax 请求开始时运行。如果已经有另一个 Ajax 请求正在进行,则它不应该运行。 ajaxStop 函数在所有 Ajax 请求停止时运行。如果有其他 Ajax 请求,它不应该运行。如果我没有看到更好的结果,我仍然可以尝试你的答案。
  • 根据 jQuery 的源代码 (github.com/jquery/jquery/blob/master/src/ajax.js#L659-661),jQuery 正在使用一个公共可用的计数器 jQuery.active。我确认您可以使用它来触发全局事件。示例: beforeSend: function(){if(jQuery.active === 0) {$.event.trigger('ajaxStart')}}
【解决方案3】:

尝试在您的 ajax 请求中使用 global: false,例如:

 $.ajax({
   url: "test.html",
   global: false,
   // ...
 });

来源:: http://docs.jquery.com/Ajax_Events

查找全局事件。

【讨论】:

  • 我试过了,它禁用了所有全局 ajax 处理程序。我只是想禁用某些全局 ajax 处理程序。
  • 这对类似的问题很有帮助。谢谢!
  • 这是我认为最好的答案
  • @AbrarJahin 答案实际上是错误的,因为问题是如何禁用 only ajaxError 事件而不禁用 任何其他 全局事件。这个答案禁用了所有全局事件,所以完全错误
【解决方案4】:

您可以将$.event.global.ajaxError 设置为false 以暂时禁用调用全局错误回调。使用您的特殊请求的 error 和 complete 回调来设置标志:

$.ajax({
    url: 'some.domain.com/',
}).error(function(jXHR){
    // Disable global error logging
    $.event.global.ajaxError = false;
}).complete(function(){
    // Enable global error logging
    $.event.global.ajaxError = true;
});

jsFiddle 上提供了一个示例。

我想补充一点,我仍然更喜欢 Jon 的提议。这种技术需要在 2 个地方设置标志,您可能会忘记其中一个,并且会意外禁用全局处理程序。另一个原因是,应该保证 Jon 的技术可以在设置一些内部标志不可靠的 jQuery 版本中工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多