【问题标题】:How to javascript submit in the presence of an input id equal to 'submit'如何在存在等于“提交”的输入 ID 的情况下进行 javascript 提交
【发布时间】: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() 的无限循环。

标签: javascript jquery forms namespaces


【解决方案1】:

如果表单元素的名称或 ID 为“提交”,则会发生错误。看来是 jQuery 的问题。

【讨论】:

  • 与 jQuery 无关。问题是 .符号将找到带有 id 提交的元素(因为它是表单的属性)而不是方法..
【解决方案2】:

你需要而不是form.submit();

$(form).submit();

这是因为form 只是裸DOM 元素,而$(form) 是jQuery 对象。调用form.submit() 试图访问formsubmit 属性。由于它没有,它默认获取idsubmit 的子元素的老式行为(因此“不是函数”错误)。

【讨论】:

  • @Emmett 您可以编辑此答案以反映您的改变吗? :)
  • @yc 这并不是真正的改变心意。有两个问题。我在这个答案中描述的第一个导致“不是函数”错误。第二个问题是 jQuery 错误。如果您正在寻找标记为已接受的答案,我可以谦虚地建议我的其他答案;)stackoverflow.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

【讨论】:

    猜你喜欢
    • 2010-12-26
    • 2019-11-05
    • 1970-01-01
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-05
    • 1970-01-01
    相关资源
    最近更新 更多