Jquery绑定是惊人的,但我不知道绑定发生的顺序。我现在的问题是:
$(document.body).delegate('form', methods.checkForm);
$('form').bind('submit', methods.submitFormIfCheckedFormIsTrue);
methods.checkForm = function (e) {
if (!$(this).isVerified()) {
return false;
}
return true;
};
methods.submitFormIfCheckedFormIsTrue = function (e) {
e.preventDefault();
$.ajax("/submitForm", {
data:$(this).serialize(),
type:"post"
});
};
这显然不是我正在使用的实际代码,但它非常接近。会发生什么,commitFormIfCheckedFormIsTrue函数在checkForm函数之前或期间触发,因此检查非常无用。我的黑客是将“已检查”类添加到表单中并检查表单是否在其他函数中具有该类...但是然后单击提交,它会检查,然后您必须再次单击它以提交它如果一切顺利......那是迟钝的。
对于这个问题而言,另一件重要的事情是,由于无法改变的原因,我在应用程序中处于完全不同的部分。而且,它们是异步加载的。
我想知道的主要事情是...如何更改顺序,或以某种方式设置事件的优先级......
答案 0 :(得分:3)
如果您在示例中使用“委托”,那么ajax提交总是先运行,因此对您的问题的简短回答是“你不能”。您的委托附加到'body'元素,因此附加到DOM树中更靠近表单的元素的事件将首先触发。
来自表单的事件泡沫 - >身体,所以当你这样做时没有排序。
一种选择是让您的验证触发第二次事件。
methods.checkForm = function (e) {
e.preventDefault()
if ($(this).isVerified()) {
$(this).trigger('form-verified');
}
};
然后,不将其他处理程序绑定到'submit'
,而是将其绑定到'form-verified'
。
$('form').bind('form-verified', methods.submitFormIfCheckedFormIsTrue);
如果它们附加到同一个元素而不是使用委托,这也是完成排序事件的另一种方法。
此外,如果您使用的是jQuery> = 1.7,那么您应该使用on
而不是bind
和delegate
。 http://api.jquery.com/on/
<强>更新强>
如果两者都绑定到同一元素,则它们将按照它们附加到元素的顺序触发。假设checkForm绑定在另一个之前,那么问题是return false;
如果它们附加到同一元素,则不会阻止其他事件触发。为此,您还需要e.stopImmediatePropagation()
。
methods.checkForm = function (e) {
e.preventDefault()
if (!$(this).isVerified()) {
e.stopImmediatePropagation();
}
};
如果你不得不调整事件的顺序,这里也有一个有用的答案。 jQuery event handlers always execute in order they were bound - any way around this?
答案 1 :(得分:0)
在一般意义上,事件处理程序将按它们绑定的顺序调用,但前提是它们绑定在同一级别。在您的情况下,您将一个直接绑定到表单,而另一个是绑定在document.body
级别的委托处理程序。直接绑定的将首先发生,然后事件冒泡,由另一个处理。
如果您将两个处理程序与.delegate()
绑定在同一级别,则应按顺序调用它们:
$(document.body).delegate('form', 'submit', methods.checkForm);
$(document.body).delegate('form', 'submit',
methods.submitFormIfCheckedFormIsTrue);
然后在第一个(通用)处理程序中,您应该调用event.stopImmediatePropagation()
method以防止调用其他处理程序(注意只是返回false会阻止默认值并停止事件冒泡进一步,但它不会阻止其他该级别的处理程序来自运行):
methods.checkForm = function (e) {
if (!$(this).isVerified()) {
e.stopImmediatePropagation();
return false;
}
return true;
};
(顺便说一句,问题中显示的代码遗漏了.delegate()
调用中的事件(第二个参数) - 我已将其放入我的代码中。)
或者直接绑定两个处理程序而不是使用.delegate()
。说到使用.delegate()
,如果您使用的是最新版本的jQuery,您可能希望切换到使用新的do-everything事件绑定方法.on()
。
“会发生什么,在checkForm函数之前或期间触发submitFormIfCheckedFormIsTrue函数”
绝对是在之前,而不是在期间。 (在几乎所有浏览器中)JavaScript在单个线程上运行,因此您不会同时运行两个函数。