如何在存在等于“提交”的输入 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() 试图访问formsubmit 属性。由于它没有,它默认获取idsubmit 的子元素的老式行为(因此“不是函数”错误)。

【讨论】:

@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 提交的主要内容,如果未能解决你的问题,请参考以下文章

如何判断是不是存在SQL注入以及注入类型?

如何使用 JavaScript 在没有提交按钮的情况下提交“文件”输入?

如何在没有按钮的情况下提交表单?

如何启用/禁用提交按钮,仅在提供两个条件的情况下:检查输入单选和填充输入文本

如何使用 ajax Post 方法在没有 jQuery 的情况下提交用户输入

提交联系表 7 后如何防止在未输入必填字段的情况下重定向到某个 URL