javascript - 如何避免 2 个 jQuery "on form submit"脚本之间的冲突?

标签 javascript jquery ajax forms

我想要实现的是跟踪表单提交。 但是由于我们对提交按钮使用了很多变体,所以我想更改我当前的代码:

$(document).on('click','input[type="submit"], button[type="submit"]',function(){

通用的东西。我相信最好的方法是 $("form")-annotation。

问题是,例如,如果 form 上有一个 ajax 脚本,它会被我的 additional 脚本代码阻止。 基本上我想要实现的是拥有两个世界。

所以第一个是网站目前拥有的(虽然不是每个网站):

$("form").submit(function () {
  // ....do something, maybe ajax submit of the form.....
});

和我想添加的附加而不编辑网站中已找到的任何当前脚本:

$("form").submit(function () {
    $.getJSON("....");
});

我的解决方案应该是第二个脚本(附加的)不会干扰任何其他表单脚本。

一个想法

使用jQuery addClass为当前页面的表单添加一个类。

有什么解决方案?

最佳答案

我创建了一个小片段来演示这个问题:

$(document).ready(function() {

  // Registering form-submission as the first would be a possibility
  $('form').on('submit', function(e) {
    console.log(e.target);
    console.info('My first callback is executing');

    // Do some stuff here, but don't mess with the event-object 
    // (like preventing default or stopping the event-chain)
  });

  // Then afterwards everything else that *might* catch the event
  $('form').on('submit', function(e) {
    console.log(e.target);
    console.info('My second callback is executing');

    // Usually some Ajax-Handler-Callback, that handles sending the form,
    // will preventDefault() and stopImmediatePropagation() - that is why 
    // your general first listener must be registered before any of these callbacks

    console.warn('Second callback stops the event from bubbling/propagating');
    e.stopImmediatePropagation();
    e.preventDefault();
  });

  // This will never happen
  $('form').on('submit', function(e) {
    console.log(e.target);
    console.info('My third callback will never execute');
  });
  
  // Using a delegated event-listener with `useCapture` lets this execute first
  document.addEventListener('submit', function(e) {
    console.info('Capturing the event natively');
  }, true);

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<h1>My Website with a multi-handled form</h1>

<form class="" action="" method="post">
  <input type="text" name="test" value="">
  <button type="submit" name="button">Send</button>
</form>


提交表单时代码段的输出:

Capturing the event natively

<form class action method="post">…</form>

My first callback is executing

<form class action method="post">…</form>

My second callback is executing
Second callback stops the event from bubbling/propagating


刚刚发生了什么?

通过按下提交按钮,我们的表单发出提交事件。浏览器以指定的 event-order 中的事件传播开始.事件传播有两个阶段:event-capturing and event-bubbling .

现在我们的第一个调用事件监听器是带有useCapture指令的监听器。
这是在事件传播捕获阶段期间。

useCapture 的解释来自 MDN :

capture: A Boolean that indicates that events of this type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree.

完成后,浏览器从事件传播冒泡阶段开始。

这是所有 $('element').on()element.addEventListener() 的地方(没有 useCapture 选项)已注册的监听器按出现顺序调用。

在此阶段,我们的第二个监听器不仅防止默认(不以标准方式提交表单),而且还通过调用 e.stopImmediatePropagation() 停止事件传播。

在那之后,事件链/事件传播立即停止。

这就是为什么我们的第三个监听器永远不会执行。

On a side note: When using jQuery and exiting an event-callback with return false, jQuery will execute e.preventDefault() and e.stopPropagation() automatically.

See: http://api.jquery.com/on/


结论

您的场景基本上有两种可能性:

  1. 首先注册您的默认通用事件监听器(片段中的第一个事件注册)。

  2. 在捕获阶段注册一个事件监听器,以在冒泡阶段的其他监听器被调用之前捕获事件并处理事情(代码段中的最后一个事件注册)。

    <

使用这两种方法,您应该能够在不干扰其他事件监听器的情况下完成您的工作。

关于javascript - 如何避免 2 个 jQuery "on form submit"脚本之间的冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37618816/

相关文章:

javascript - 如何使用crypto-js加密/解密

javascript - 我的循环没有移至数组中的下一个元素

javascript - Laravel 中使用 jQuery 进行 Ajax 错误 500

javascript - MVC3 AJAX 将数据传递到 Controller 。已提交两次

ajax - 如何在 MVC3 中的 Ajax Post 中使用相对 URL

javascript - SetInterval 是否在单独的线程上运行?该方法如何工作?

javascript - hrefs的空列表通过JavaScript onclick函数实现分页

javascript - 页面刷新或更改时保存通过 Redux 传递的数据时出现问题

javascript - 如何将 jQuery 过滤器添加到 html 表中?

jquery - 向其子级添加类