如何从表单提交事件中获取导致提交的按钮?

hun*_*ter 103 jquery webforms

我正在尝试找到触发表单提交的提交按钮的值

$("form").submit(function() {

});
Run Code Online (Sandbox Code Playgroud)

我可以触发一个$("input [type = submit]").每个按钮的click()事件并设置一些变量,但这似乎不如在提交时从表单中拉出按钮的优雅.

Bol*_*wyn 104

document.activeElement在这个答案中概述了:如何使用jQuery获得聚焦元素?

$form.on('submit', function() {
    var $btn = $(document.activeElement);

    if (
        /* there is an activeElement at all */
        $btn.length &&

        /* it's a child of the form */ 
        $form.has($btn) &&

        /* it's really a submit element */
        $btn.is('button[type="submit"], input[type="submit"], input[type="image"]') &&

        /* it has a "name" attribute */
        $btn.is('[name]')
    ) {
        console.log("Seems, that this element was clicked:", $btn);
        /* access $btn.attr("name") and $btn.val() for data */
    }
});
Run Code Online (Sandbox Code Playgroud)

我利用了这个事实,点击它后按钮始终是聚焦元素.如果您在点击后立即执行此操作,则无效blur().

@Doin发现了另一个缺点.如果用户enter在文本字段中提交表单,document.activeElement则不会设置.您需要通过处理类似的keypress事件来自己注意这一点input[type="text"].

更新2017-01:对于我的库Hyperform我选择不使用activeElement但是捕获所有事件,导致表单提交.这个代码在Github上.

如果您碰巧使用Hyperform,则可以使用触发提交的按钮:

$(form).on('submit', function(event) {
  var button = event.submittedVia;
});
Run Code Online (Sandbox Code Playgroud)

  • 遗憾的是,**你不能只依赖`activeElement`**,因为可以定义“提交者”: A. 通过_真实点击激活_(直接用鼠标或键盘点击空格/回车);B.通过_合成点击激活_(`buttonElement.click()`或`buttonElement.dispatch(new MouseEvent(...))`,没有获得焦点);C. 通过 _form 隐式提交_(与其他表单字段的键盘交互) D. to none, when `formElement.submit()` (8认同)
  • 只是为了保持最新状态.截至目前,Safari在单击提交按钮时将activeElement设置为文档正文.我在Safari 9.1上遇到了这个问题 (4认同)
  • 嗯...如果通过[Enter]汇总表单,这是否有效?Spec说这应该等同于单击默认的提交按钮,但我不确定它是否将它作为活动元素. (2认同)

hun*_*ter 34

我实现了这个,我想它会这样做.

$(document).ready(function() {
    $("form").submit(function() { 

    var val = $("input[type=submit][clicked=true]").val()

    // DO WORK

});
Run Code Online (Sandbox Code Playgroud)

这是设置它的提交按钮事件

$("form input[type=submit]").click(function() {
    $("input[type=submit]", $(this).parents("form")).removeAttr("clicked");
    $(this).attr("clicked", "true");
});
Run Code Online (Sandbox Code Playgroud)

感谢您的回复,但这并不是非常优雅......

  • 不是这样,这正是它的意图 (3认同)
  • 是否保证在表单提交事件之前触发click事件?我建议给表单一个`doNotSubmit`类,在提交函数内检查是否该类不存在(否则不提交),在click事件中删除表单类`doNotSubmit`并执行$('' .myForm ')引发(' 提交"); 将提交按钮值添加为隐藏字段后 (2认同)
  • @Hafenkranich在Chrome上的一些罕见情况下,点击事件在提交事件后触发. (2认同)
  • @j4k3 有更好的解决方案吗?这个答案是 8 岁 (2认同)

Tob*_*hor 17

现在submitter提交事件中有一个标准属性。
已经在 Firefox 75 和 Chrome/Edge 81 中实现

document.addEventListener('submit',function(e){
    console.log(e.submitter)
})
Run Code Online (Sandbox Code Playgroud)

对于不支持它的浏览器,请使用此polyfill
注意:如果您针对较旧的浏览器,则需要 polyfill 其他内容,例如closestmatches。并确保在添加提交事件之前加载了 polyfill。

!function(){
    var lastBtn = null
    document.addEventListener('click',function(e){
        if (!e.target.closest) return;
        lastBtn = e.target.closest('button, input[type=submit]');
    }, true);
    document.addEventListener('submit',function(e){
        if ('submitter' in e) return;
        var canditates = [document.activeElement, lastBtn];
        lastBtn = null;
        for (var i=0; i < canditates.length; i++) {
            var candidate = canditates[i];
            if (!candidate) continue;
            if (!candidate.form) continue;
            if (!candidate.matches('button, input[type=button], input[type=image]')) continue;
            e.submitter = candidate;
            return;
        }
        e.submitter = e.target.querySelector('button, input[type=button], input[type=image]')
    }, true);
}();
Run Code Online (Sandbox Code Playgroud)

  • 请注意,Apple Safari 仍然不支持此功能! (5认同)

Dav*_*son 9

我创建了一个测试表单并使用Firebug以这种方式获取值;

$('form').submit(function(event){
  alert(event.originalEvent.explicitOriginalTarget.value);
}); 
Run Code Online (Sandbox Code Playgroud)

不幸的是,只有Firefox支持此事件.

  • **只有Firefox**支持此活动. (10认同)
  • IE没有这个属性(explicitOriginalTarget) (5认同)

Jon*_*sch 6

这是一种看起来更清洁的方法.

首先,对于任何和所有形式:

$('form').click(function(event) {
  $(this).data('clicked',$(event.target))
});
Run Code Online (Sandbox Code Playgroud)

当为表单触发此单击事件时,它只记录稍后要访问的原始目标(在事件对象中可用).这是一个相当广泛的笔划,因为它将触发表单上任何位置的任何单击.欢迎优化评论,但我怀疑它永远不会引起明显的问题.

然后,在$('form').submit()中,您可以查询最后点击的内容,例如

if ($(this).data('clicked').is('[name=no_ajax]')) xhr.abort();
Run Code Online (Sandbox Code Playgroud)