我一直在将提交事件绑定到表单,并确保它们不会破坏表单,使用这样的jQuery:
jQuery('form').submit(function(e){
var form = this;
e.preventDefault();
alert('1');
setTimeout(function() {
alert('2');
form.submit();
}, 1000);
});
这一切都很好,除非,如果由于某种原因,前端开发人员给这个表单的子输入id =“submit”,这会中断,因为form.submit()
会抛出JavaScript错误(In Chrome,'未捕获TypeError:对象#的属性'提交'不是函数')。
你可以在这里看到一个例子:http://jsfiddle.net/q68ky/(如果没有<input id="submit">
,这是行为:http://jsfiddle.net/JpXzL/
现在,我知道我可以阻止这个绑定带有jQuery('form').not(:has('#submit')).submit()
id为'submit'的子节点的表单,并且表单处理得很好,但我的绑定永远不会触发那些表单。
所以,问题是:如何安全地将此jQuery函数绑定到所有表单,包括那些<input id="submit">
的表单?
编辑:值得注意的是,如果我取消绑定提交处理程序然后在jQuery(form)
上触发jQuery提交,则此问题不会消失。
答案 0 :(得分:4)
我能想到的唯一方法:
(function () {
var method;
window.submit = function (theForm) {
if (!method) {
method = document.createElement("form").submit;
}
method.call(theForm);
};
}());
然后拨打submit(theFormYouWantToSubmit)
。
您可以在此处看到它:http://jsfiddle.net/q68ky/2/
编辑:提供一些有关此功能的解释....
此方法创建一个新的表单元素(document.createElement("form")
),并存储对其“submit”属性的引用(method = document.createElement("form").submit
)。因为这是一个新创建的表单元素,没有子节点,我们可以保证“submit”属性实际上是我们需要的“submit”方法,而不是id / name为“submit”的子节点。
然后我们使用call
方法(Function.prototype
的一部分),它将submit
方法的上下文设置为我们要提交的表单,而不是{{1}对象,它本来就是它。
代码段中的其余gubbins缓存了window
方法,因此每次要提交表单时都不会发生所有这些(虽然很小)开销,并在一个方法中捕获缓存的方法本地范围,而不是将其保留在全局范围内并污染全局命名空间。
答案 1 :(得分:4)
由于这实际上是一个非jQuery问题,这里是一个非jQuery解决方案:
HTMLFormElement.prototype.submit.call(form);
更新: Access to the DOM prototypes is only possible in IE8+. (这可能是jQuery不使用它的原因)。
@Matt's answer应该可以在任何浏览器中使用
答案 2 :(得分:2)
另外我在my other answer中发现的问题,有一个开放的jQuery错误加剧了这个问题:
.SUBMIT()如果有ID =“提交”则可能失败
如果ID为提交的元素 以.submit()形式存在,可能会失败。 这个功能很重要(在 特别是)正常工作。
答案 3 :(得分:0)
而不是form.submit();
,您需要
$(form).submit();
这是因为form
只是裸DOM元素,而$(form)
是jQuery对象。致电form.submit()
正在尝试访问submit
的{{1}}属性。因为它没有一个,所以它违反了老派的行为,即获取form
为id
的子元素(因此“不是函数”错误)。
答案 4 :(得分:-1)
如果表单元素的名称或标识为“提交”,则会出现错误。看起来这是jQuery的一个问题。