Firefox 不会阻止发送的提交事件

Posted

技术标签:

【中文标题】Firefox 不会阻止发送的提交事件【英文标题】:FIrefox doesn't preventing dispatched submit event 【发布时间】:2018-09-10 07:01:06 【问题描述】:

无语fiddle with reproducing of situation

关键代码是:

class Form extends React.Component 
    handleSubmit(evt) 
        evt.preventDefault()

        var data = 
        for (var i = 0; i < this.form.elements.length; i++) 
        var elt = this.form.elements[i]
          if (elt.name) 
            data[elt.name] = elt.value
          
        

        this.props.onSubmit(data)
        return false
    

    submit() 
        if (this.form.checkValidity())
            this.form.dispatchEvent(new Event('submit'))
    

    render() 
        return (
            <form onSubmit=this.handleSubmit.bind(this) ref=r => this.form = r>
                this.props.children
            </form>
        )
    

this.form.dispatchEvent() 之后,handleSubmit() 中的evt.preventDefault() 在 Firefox 中不起作用

如果您在 Chrome 中打开 fiddle(例如)并在字段中输入数据,您将在控制台中看到它 - 防止调度事件将完美运行。

在 Firefox 中阻止不起作用 - 记录数据后页面立即重新加载(请参阅控制台中的“APP CONSTRUCTOR”)。

所以,问题很明显:如何避免这个错误?

【问题讨论】:

你试过event.stopPropagation() 吗? @Meir 是的,仍然没有变化。更新小提琴 看起来evt 实际上是代理而不是事件? (不确定是否相关) @PaulS。是的,但evt.nativeEvent 是原生事件,evt.nativeEvent.preventDefault() 没有变化 【参考方案1】:

首先,这不是一个特定于反应的问题。

如何避免这个错误?

在这种情况下, cancelable: true 标志似乎阻止了 Firefox 重新加载页面。

this.form.dispatchEvent(new Event('submit',  cancelable: true ))

这是一个完整而简单的例子:

<!Doctype html>
<html>
  <head>
    <script type="text/javascript">
      document.addEventListener("DOMContentLoaded", function(event) 
        const form = document.querySelector('#testform');
        const button = form.querySelector('button');

        form.onsubmit = function (e) 
          e.preventDefault();
          e.stopPropagation();

          console.log('submitting the form ...');
          
          // return true;
          return false;
        ;

        // https://developer.mozilla.org/en-US/docs/Web/API/Event/Event
        // cancelable: (optional) a Boolean indicating whether the event can be cancelled. The default is false.
        const submitEvent = new Event('submit',  
          cancelable: true
        );

        // https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted
        // The isTrusted read-only property of the Event interface is a boolean that is true when the event was generated by a user action, and false when the event was created or modified by a script or dispatched via dispatchEvent.
        console.log('is event trusted', submitEvent.isTrusted) // false
        console.log('is event cancelable', submitEvent.cancelable) // true

        button.onclick = function () 
          console.log('button clicked');
          const cancelled = form.dispatchEvent(submitEvent);
          // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent
          // The return value is false if event is cancelable and at least one of the event handlers which handled this event called Event.preventDefault(). Otherwise it returns true.
          console.log('is cancelled', !cancelled);
        
      );
    </script>
  </head>
  <body>
    <form id="testform">
      <input type="hidden" name="a" value="b">
      <p>Hit the button a couple times, the page should not refresh.</p>
      <button type="button">click</button>
    </form>
  </body>
</html>

为什么会这样:

https://www.chromestatus.com/features/5718803933560832 根据 UI 事件规范,不受信任的事件(即由 JavaScript 创建的事件)不应调用默认操作。

如果您将可取消标志更改为 false 并尝试在 Chrome 中进行测试,它仍然可以工作,因为(据我所知)它仍然是一个不受信任的事件(不是由用户与 UI 的直接交互创建的)并且 Chrome 确实如此不为不受信任的事件运行默认处理程序。

但是,我不确定为什么 Firefox 仍然为不受信任的事件运行默认处理程序。

【讨论】:

感谢您的回答。似乎它解决了问题) 谢谢,你是山羊! 感谢您拯救我的一天!

以上是关于Firefox 不会阻止发送的提交事件的主要内容,如果未能解决你的问题,请参考以下文章

JS事件防止链接打开 URL:

兼容firefox,ie,谷歌,阻止浏览器冒泡事件,Firefox不支持event解决方法

FormData() 对象不会从表单添加提交类型的输入,而在 Firefox 上

阻止浏览器冒泡事件,兼容firefox和ie

如何防止 Selenium 3.0 (Geckodriver) 创建临时 Firefox 配置文件?

当 CSS 链接在头部时,Firefox 不会阻止 HTML 的呈现