确定哪个元素触发了表单提交事件

Determine which element triggered a form submit event

我会先说我非常熟悉点击事件,并且知道我可以在表单提交按钮上注册点击事件,正如许多其他答案所解释的那样。我的问题更深一层。

表单可以通过单击提交以外的其他方式提交:我在想当用户在专注于 input/select 时按回车键,甚至在专注于 space 时按回车键或在专注于提交按钮本身……我希望能够获得对提交表单的元素的引用。

This answer seemed to have promise, but I'm not exactly sure how to 'see' the values he mentions. I made a codepen进行演示。 *编辑:我更新了代码笔以反映下面接受的答案。

看起来答案实际上是不准确的,因为当用户提交表单时,浏览器会在表单中第一次提交时触发点击事件,不是在触发提交的元素之后首先提交(至少当我 运行 那个 Codepen 在 Chrome/Firefox/Safari 时)。

为了说明为什么这是必要的,我正在研究 Asp.NET site where every page's content is encapsulated in a monolithic form。我在异步提交的页脚中添加了一个电子邮件订阅表单……这意味着我需要对事件执行 e.preventDefault(),并且如果表单实际上是从其他地方(如搜索)提交的,我还想避免意外提交顶部栏或我不知道的表格。

您可以使用 document.activeElement 这将适用于点击以及当用户切换到按钮并按下回车按钮时。

监听表单上的提交事件,然后在回调内部,引用 document.activeElement,它将是用户点击或跳转到的按钮。

示例: http://codepen.io/anon/pen/KVoJrJ

<form> 元素的提交事件实际上包含对 submitter:
的引用 https://developer.mozilla.org/en-US/docs/Web/API/SubmitEvent/submitter

form.onsubmit = (event) => {
    const formElement = event.target;
    const formSubmitter = event.submitter;
    console.log("The form element itself", formElement);
    console.log("The submitter of the form (usually an HtmlInputElement)", formSubmitter);

    const formData = new FormData(formElement);
    if(formSubmitter) formData.set(formSubmitter.name, formSubmitter.value);

    fetch(formElement.action, {
        method: formElement.method,
        body: formData,
    })

    event.preventDefault();
}

注意:检查此功能的兼容性。

使用submitter

event.nativeEvent.submitter 会给你启动提交的按钮

submit(event){

    if (event.nativeEvent.submitter.id == "button2") { //do whatever }

}