【问题标题】:How to submit a form that has been intercepted with event.preventDefault()如何提交被 event.preventDefault() 拦截的表单
【发布时间】:2014-02-21 21:53:41
【问题描述】:

我有一个 id="edit_profile" 的普通表单。

当表单提交时,我想拦截它并检查我是否需要通过 google maps api 对地址进行地理编码,如果不需要,则继续提交。

类似:

$('#edit_profile').on('submit', function(event) {
    event.preventDefault();
    if ( some test ) {
        geocode_address( address, this ); // the api callback will handle form submit
    } else {
    // we want to go ahead and submit the form
    this.submit();
    }
});

问题是this.submit()正在抛出错误TypeError: Property 'submit' of object #<HTMLFormElement> is not a function

我最近读了一些东西,但现在找不到关于必须使用原生 JavaScript 来提交表单而不是 jQuery(我猜是因为表单提交的 jQuery 事件处理程序已经被告知要防止默认)。

但如果我尝试一些变体,例如 document.getElementById('edit_profile').submit();document.forms[0].submit();,我会得到相同的错误或类似的错误。

【问题讨论】:

    标签: javascript jquery forms form-submit preventdefault


    【解决方案1】:

    DOM 元素没有方法 .submit -- 但 jQuery 对象有(仅在 form 元素上) -- 基本上,您忘记在 jQuery 中包装 this

    $(this).submit();
    

    参考:https://api.jquery.com/submit/

    编辑:

    我知道你从哪里得到“无限循环”场景。当您单击提交 button 而不是表单实际提交时,您实际上应该设置处理程序以触发。

    到目前为止,您捕获表单submit 操作并阻止默认操作(即提交)- 然后您做一些事情并在this 上调用submit。好吧,这将触发表单submit 的处理程序,这将再次阻止默认操作!因此,简而言之,在您的提交按钮上放置一个处理程序,阻止默认操作,执行逻辑,然后调用$("#edit_profile").submit()

    【讨论】:

    • 真的吗?我经常阅读有关本机 javascript 表单提交的信息,例如这里:w3schools.com/jsref/met_form_submit.asp 包装 'this' 使其成为 jQuery 对象会设置一个无限循环。
    • this 包裹到一个jQuery 对象中不会设置无限循环,您需要在jQuery 中一直使用$(this)
    • 但是你不需要jquery来使用this,如果你想使用jquery来操作this,你只需要使用$(this)。无限循环可能是错误的错误名称,但无论如何我都粘贴在这里太长了。使用 $(this) 意味着我正在拦截表单提交,然后提交它,拦截该提交,提交它,拦截 that 提交,提交等。
    • @terraling - 认为我们俩可能有点困惑,this 是指您的form 元素,还是被点击的按钮?当您单击提交按钮时,您的函数应该正在运行,然后您阻止默认操作,然后定位表单并调用 submit - 不要阻止表单本身的默认操作。
    • 首先,感谢您花时间在这上面。我将尝试拦截点击而不是提交,尽管我会指出提交()api.jquery.com/submit)的 jquery 文档使用拦截表单提交而不是按钮点击的示例,因此可能需要在此案例,但我一般不会驳回它。我会回来报告...
    【解决方案2】:

    我正在回答我自己的问题,因为解决方案出乎意料且简单,值得重复。完全感谢 Chris Butler 回答了这个相关问题:Unable to `submit()` an html form after intercepting the submit with javascript(注意,他不是公认的答案)。

    回答:如果您命名 & #id 您的提交按钮“提交”,这将与本机 JavaScript .submit() 方法的名称发生冲突,该方法将不再起作用并给出问题中描述的类型错误。

    因此,在我的情况下,解决方案是将我的提交按钮重命名为其他名称。

    回顾一下:

    要拦截表单提交,您可以拦截单击提交按钮或拦截表单提交本身。如果您的目标是拦截表单提交,那么就这样做,而不是提交按钮上的单击事件,因为表单可以通过其他事件提交,例如在文本字段上按 Enter。

    如果您通过 jQuery 拦截表单,例如$("#myForm").on("submit", function() {...}) 然后继续将提交处理传递给另一个函数(例如,在调用地理编码 api 的问题中)然后 that 函数将需要通过以下方式触发表单提交直接作用于 DOM 表单元素(例如 `document.getElementById('myForm').submit() ),它将在不触发 onsubmit 事件的情况下提交表单,因此不会再次触发初始拦截,从而创建无限循环如果你使用 jQuery 来触发提交。

    【讨论】:

      【解决方案3】:

      为什么不像这样重新排列代码

      $('#edit_profile').on('submit', function(event) {
        if ( some test ) {
          event.preventDefault();
          geocode_address( address, this ); // the api callback will handle form submit
        } else {
          // we want to go ahead and submit the form
          // this.submit(); // no need to call explicitly
        }
      });
      

      如果您想在 some test 中进行回调,这将不起作用,但从您的代码中看起来不是这样。

      【讨论】:

      • 谢谢amitamb。快速注意指出,在您的示例中 else { } 子句实际上是多余的,因为在 if 测试失败后,在匿名函数的末尾有一个隐式返回 true 无论如何都会触发提交。
      猜你喜欢
      • 1970-01-01
      • 2019-08-03
      • 1970-01-01
      • 2012-04-09
      • 2013-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多