如何在存在等于“提交”的输入 ID 的情况下进行 javascript 提交
Posted
技术标签:
【中文标题】如何在存在等于“提交”的输入 ID 的情况下进行 javascript 提交【英文标题】:How to javascript submit in the presence of an input id equal to 'submit' 【发布时间】:2011-05-26 18:54:11 【问题描述】:我一直在将提交事件绑定到表单,并确保它们不会破坏表单,使用这样的 jQuery:
jQuery('form').submit(function(e)
var form = this;
e.preventDefault();
alert('1');
setTimeout(function()
alert('2');
form.submit();
, 1000);
);
这一切都很好,除了,如果由于某种原因前端开发人员为此表单的子输入提供了 ="submit" 的 id,这会中断,因为form.submit()
会引发 javascript 错误(在 Chrome 中, '未捕获的类型错误:对象#的属性'提交'不是函数')。
您可以在此处看到发生这种情况的示例: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 提交,这个问题不会消失。
【问题讨论】:
我知道一个理想的世界,我不应该在输入表单上创建id="submit"
,但我不能保证它不会存在。
@ys,你明白这段代码会导致死循环吧?
@Gaby 不,form.submit()
在 DOM 元素上触发提交,而不是 jQuery 元素。如果它是$(form).submit();
你是对的,我需要取消绑定 jQuery 处理程序,就像这里:jsfiddle.net/LKUhV。此外,正如您在原始 jsfiddle 上看到的,它不会导致触发 alert()
的无限循环。
【参考方案1】:
如果表单元素的名称或 ID 为“提交”,则会发生错误。看来是 jQuery 的问题。
【讨论】:
与 jQuery 无关。问题是 .符号将找到带有 id 提交的元素(因为它是表单的属性)而不是方法..【参考方案2】:你需要而不是form.submit();
$(form).submit();
这是因为form
只是裸DOM 元素,而$(form)
是jQuery 对象。调用form.submit()
试图访问form
的submit
属性。由于它没有,它默认获取id
为submit
的子元素的老式行为(因此“不是函数”错误)。
【讨论】:
@Emmett 您可以编辑此答案以反映您的改变吗? :) @yc 这并不是真正的改变心意。有两个问题。我在这个答案中描述的第一个导致“不是函数”错误。第二个问题是 jQuery 错误。如果您正在寻找标记为已接受的答案,我可以谦虚地建议我的其他答案;)***.com/questions/4465028/…【参考方案3】:我能想到的唯一方法:
(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")
),并存储对其“提交”属性的引用 (method = document.createElement("form").submit
)。因为这是一个新创建的表单元素,没有子节点,我们可以保证“submit”属性其实就是我们需要的“submit”方法,而不是id/name为“submit”的子节点。
然后我们使用call
方法(Function.prototype
的一部分),它将submit
方法的上下文设置为我们要提交的表单,而不是window
对象,这就是它的作用否则打开。
sn-p 中的其余 gubbins 缓存 submit
方法,因此所有这些(尽管很小)开销不会在您每次要提交表单时发生,并将缓存的方法捕获在一个本地作用域,而不是将其保存在全局作用域中并污染全局命名空间。
【讨论】:
显然一个 jQuery 提交者尝试了这个,但它产生了一些 IE6 问题。 bugs.jquery.com/ticket/1414他们已将其切换为“不会修复”。【参考方案4】:由于这实际上是一个非jQuery的问题,这里是一个非jQuery的解决方案:
htmlFormElement.prototype.submit.call(form);
DEMO
参考:HTMLFormElement
更新:Access to the DOM prototypes is only possible in IE8+.(这可能是 jQuery 不使用它的原因)。
@Matt's answer 应该可以在任何浏览器中使用
【讨论】:
干净,我喜欢。更广泛地使用它有什么缺点吗?而且,为什么 jQuery 不将它用于submit()
?
@yc:嗯,我总是不确定 IE 是如何实现所有这些东西的。但是我这里没有 IE 可以测试...方法本身(从原型中获取原始方法)被广泛用于避免这种情况(覆盖属性)。
"我这里没有 IE 可以测试..." - 这是什么天堂,我如何到达那里?
@ScottSEA:获得 Mac ;)(或任何 UNIX/Linux 发行版,永远不要再安装 Windows!)【参考方案5】:
除了我在my other answer 中发现的问题之外,还有一个开放的 jQuery 错误加剧了该问题:
.SUBMIT() 如果有 ID="SUBMIT" 可能会失败
如果一个元素的 ID 为 submit 存在于表单中, .submit() 可能会失败。 这个函数很重要(在 特别)工作正常。
http://bugs.jquery.com/ticket/1414
【讨论】:
以上是关于如何在存在等于“提交”的输入 ID 的情况下进行 javascript 提交的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 JavaScript 在没有提交按钮的情况下提交“文件”输入?
如何启用/禁用提交按钮,仅在提供两个条件的情况下:检查输入单选和填充输入文本