我想要实现的是跟踪表单提交。 但是由于我们用于提交按钮的许多变化,我想要更改当前的代码:
$(document).on('click','input[type="submit"], button[type="submit"]',function(){
通用的东西。我认为最好的方法是$("form")
- 注释。
问题是,例如,如果form
上有一个ajax脚本,它会被我的additional
脚本代码阻止。
基本上我想要实现的是拥有两个世界。
所以第一个是网站目前所拥有的(不是每个网站都有):
$("form").submit(function () {
// ....do something, maybe ajax submit of the form.....
});
以及我要添加的附加,而不修改网站上已有的任何当前脚本:
$("form").submit(function () {
$.getJSON("....");
});
我的解决方案应该是第二个脚本(附加)不会干扰任何其他表单脚本。
AN IDEA
使用jQuery addClass
向当前页面的表单添加类。
这是什么解决方案?
答案 0 :(得分:2)
我创建了一个小小的代码片段来演示这个问题:
$(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>
&#13;
提交表单时输出代码段:
本地捕获事件
<form class action method="post">…</form>
我的第一个回调正在执行
<form class action method="post">…</form>
我的第二个回调是执行
第二次回调会阻止事件冒泡/传播
按下提交按钮,我们的表单会发出 submit -event。浏览器以指定的event-order中的事件传播开始。事件传播分为两个阶段:event-capturing and event-bubbling。
现在我们的首次调用事件监听器是 useCapture -directive。 这是在事件传播的捕获阶段期间。
从MDN获取 useCapture 的说明:
capture:一个布尔值,表示此类型的事件将是 在被派遣到任何人之前派遣到注册的听众 DOM树下面的EventTarget。
完成后,浏览器将以事件传播的冒泡阶段开始。
这是所有$('element').on()
和element.addEventListener()
(没有 useCapture 选项)注册的侦听器按其显示顺序调用的地方。
在此阶段,我们的第二个监听器不仅要防止默认(不以标准方式提交表单),还要通过调用e.stopImmediatePropagation()
来停止事件传播。
之后事件链/事件传播立即停止。
这就是为什么我们的第三个听众永远不会执行。
旁注:使用jQuery并退出事件回调时
return false
,jQuery将执行e.preventDefault()
和 自动e.stopPropagation()
。
您的场景基本上有两种可能性:
在其他任何事情之前注册您的默认常规事件监听器(在Snippet中首次注册事件)。
在捕获阶段注册一个事件监听器,捕获事件并处理来自bubbling-phase get的其他监听器之前的事情(片段中的最后一次事件注册)。
使用这两种方法,您应该能够在不干扰其他事件监听器的情况下完成任务。
答案 1 :(得分:1)
使用此:
$(document).on("submit", "form", function (e){
完整示例:
<form id="form1"><input type="text" /><input type="submit" /></form>
<form id="form2"><input type="text" /><input type="submit" /></form>
JS:
$(document).on("submit", "form", function (e) {
var oForm = $(this);
var formId = oForm.attr("id");
var firstValue = oForm.find("input").first().val();
alert("Form '" + formId + " is being submitted, value of first input is: " + firstValue);
return false;
})
[JS fiddle]: http://jsfiddle.net/pZ3Jn/
答案 2 :(得分:0)
我想要实现的是跟踪表单提交。
为什么不使用$(document).on('submit', 'form', function(){});
?
无论如何提交,都会在每个表单提交时触发。
$(document).ready(function() {
// Some already existing event handler
$('#bir').on('submit', function(e) {
console.log($(this).attr('id'));
e.preventDefault();
});
// Your universal form event handler
$(document).on('submit', 'form', function(e) {
console.log('Additional functionality for: ' + $(this).attr('id'));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="bir">
<input type="submit" />
</form>
<form id="ikki">
<input type="submit" />
</form>
答案 3 :(得分:0)
之前我曾遇到过这个问题几次,我的解决方案是捕获所有表单节点并将它们与特殊操作相关联。这可能不实用,但也是一种可能的解决方案。
示例强>
//Getting all form elements
var formNodes = document.getElementsByTagName('form');
//loop through nodelist and add submit event and special class to each.
for(var i = 0; i < formNodes.length; i++){
formNodes[i].addEventListener('submit' , registerAction)
formNodes[i].className += "form-" + i;
}
/*This function captures the submitted form and determines
the action to carry out based off class name .
e.preventDefault will stop page from reloading in case of
making ajax requests.
*/
function registerAction(e){
e.preventDefault();
var formTarget = $(e.target).attr('class');
switch(formTarget){
case "form-0" :
// Do something ...
break;
case "form-1" :
// Do something else...
break;
default:
break;
}
return false;
}
请记住,registerAction中的逻辑可以根据您的需要进行更改 在这种情况下,我使用了“案例陈述”,因为我觉得它最有意义。
这不完美,但我希望它能给你一个想法......
答案 4 :(得分:0)
问题在于,例如,如果表单上有一个ajax脚本,那么 被我的附加脚本代码阻止。
不,它没有。您可以在一个元素上绑定多个处理程序。
对于极少数情况,请参阅其他建议,但如果我说得对,那么您的基本假设是绑定元素上的处理程序取消前一个。嗯,它没有。