首页 > 解决方案 > Event.preventDefault() 不起作用,表单提交了两次

问题描述

我有两个页面,两种形式基本相同,带有条纹元素,但一个有额外的字段,另一个没有。

带有额外字段的表单event.preventDefault()似乎并没有停止表单提交,因此表单被提交了两次,但没有额外字段的表单不会。

为什么是一种形式isTrusted === true而另一种形式isTrusted === false?这是什么控制的?

这可能是preventDefault()不工作的原因吗?

经过更多测试,我发现:

<%= form_tag add_card_path(@product.id), id: "payment-form" do

不提交两次,但

<%= form_with add_card_path(@product.id), id: "payment-form" do 

确实提交了两次,因此preventDefault()不起作用。

为什么会这样?

<%= form_tag add_card_path(@product.id), id: "payment-form" do %>
  <div class="form-row">
    <div id="card-errors" role="alert" class="col"></div>
  </div>
  <div class="form-row">
    <div id="card-element" class="col"></div>
  </div>
  <div class="form-row mt-3">
    <button class="btn_spinner col btn md-width-auto btn-primary">Add Card</button>
  </div>
<% end %>

Javascript:

// Handle form submission.
var form = document.getElementById(thatInstance.formId);
form.addEventListener('submit', function (event) {
  event.preventDefault();
  debugger;
  thatInstance.createStripeToken();
});

从调试器检查事件对象:

工作页面:

事件对象:

bubbles: true
cancelBubble: false
cancelable: true
composed: false
currentTarget: <form id="payment-form">
defaultPrevented: true
eventPhase: 2
isTrusted: false
returnValue: false
srcElement: <form id="payment-form">
target: <form id="payment-form">
timeStamp: 20826
type: "submit"

非工作页面:

事件对象:

bubbles: true
cancelBubble: false
cancelable: true
composed: false
currentTarget: <form id="payment-form">
defaultPrevented: true
eventPhase: 2
isTrusted: true
returnValue: false
srcElement: <form id="payment-form">
target: <form id="payment-form">
timeStamp: 23652
type: "submit"

解决方案:

需要data-remote === false,不知道为什么。

Form_with 有data-remote === true,而 form_tag 有data-remote === false.

标签: javascripthtmlruby-on-railsforms

解决方案


来自MDN关于Event.isTrusted

Event接口的isTrusted只读属性是指事件由用户操作生成的时间,以及事件由脚本创建或修改或通过 调度的时间。BooleantruefalseEventTarget.dispatchEvent()

来自MDN关于Event.preventDefault()

调用preventDefault()不可取消的事件,例如通过 调度的事件EventTarget.dispatchEvent(),而不指定cancelable: true 没有任何效果。


推荐阅读