ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

});

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

请注意,不一定有任何这样的按钮。一个脚本可能会做 formobj.submit()。我认为点击事件是要走的路。
对于现代浏览器,现在有 event.submitter,它为您提供被点击的 <button><input type="submit">
event.originalEvent.submitter
请注意,Apple Safari 也不应该被视为现代浏览器!

C
Community

我在这个答案中利用了 document.activeElementHow to get the focused element with 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 */
    }
});

我利用了这样一个事实,即按钮在单击后始终是焦点元素。如果您在点击后立即执行 blur(),这将起作用。

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

2017 年 1 月更新:对于我的库 Hyperform,我选择不使用 activeElement,而是捕获所有导致表单提交的事件。 The code for this 在 Github 上。

如果您碰巧使用 Hyperform,您可以通过以下方式访问触发提交的按钮:

$(form).on('submit', function(event) {
  var button = event.submittedVia;
});

MDN 说是。 (FF3、IE4、Chrome 2、Safari 4、Opera 9)
这应该是答案。
嗯...如果通过 [Enter] 提交表单,这是否有效? Spec说这应该相当于单击默认提交按钮,但我不确定它是否将其保留为活动元素。
遗憾的是,您不能只依赖 activeElement,因为可以定义“提交者”: A. 通过 真实点击激活(直接用鼠标或键盘点击 Space / 进入); B. 通过合成点击激活buttonElement.click()buttonElement.dispatch(new MouseEvent(...)),不获取焦点); C. 通过 form 隐式提交(键盘与其他表单的字段交互) D. 无,当 formElement.submit()
只是为了让事情保持最新状态。截至目前,Safari 在单击提交按钮时将 activeElement 设置为文档正文。我在 Safari 9.1 上遇到了这个问题
h
hunter

我实现了这一点,我想它会做到的。

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

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

    // DO WORK

});

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

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

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


不支持跨浏览器/多个提交按钮。
是否保证在表单提交事件之前触发点击事件?我建议给表单一个 doNotSubmit 类,在提交函数中检查该类是否不存在(否则不要提交),在点击事件中删除表单类 doNotSubmit 并执行 $('' .myForm').trigger('提交');将提交按钮值添加为隐藏字段后
@Hafenkranich 在 Chrome 上的一些罕见情况下,点击事件在提交事件之后触发。
@roamnoza 这正是我遇到的。
@j4k3 有更好的解决方案吗?这个答案是8岁
T
Tobias Buschor

现在提交事件中有一个标准的 submitter 属性。
Already implemented in Firefox 75 and Chrome/Edge 81

document.addEventListener('submit',function(e){
    console.log(e.submitter)
})

对于不支持它的浏览器,请使用此 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);
}();

请注意,Apple Safari 仍然不支持此功能!
注意上面的 polyfill 需要 UA 实现 Element.closest()、Element.matches() 和 Element.querySelector()。还有可能 UA 在 polyfill 中调用 your 'submit' 处理程序 before 'submit' 处理程序,而您看不到 .submitter 值。
谢谢 Mikko,我添加了一条说明如何避免这些问题。
polyfill 还应该检查按钮是否与要提交的表单实际匹配。如果页面包含例如两个表单,则从第一个表单单击的按钮可能最终由上述 polyfill 为第二个表单提交。另请注意,根据 WHATWG 规范,如果直接调用了 form.submit(),则提交者可能会丢失。
是的,我现在将 lastBtn 重置为 null。我无法理解规范中 form.submit() 的行为,因为调用 form.submit() 不会触发提交侦听器你能指出我的规范吗?
P
Paul D. Waite

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

$('form').submit(function(event){
  alert(event.originalEvent.explicitOriginalTarget.value);
}); 

不幸的是,只有 Firefox 支持这个事件。


IE 没有这个属性(explicitOriginalTarget)
好旧的 IE 把它搞砸了,通过了 Firebug,看不到任何其他要使用的对象值,但完全忘记了替代浏览器。听到它并不感到惊讶,但必须检查 Chrome。
只有 Firefox 支持此事件。
所以基本上,HTML 中有些东西在 JS 中是做不到的……Mozilla 决定实现缺失的功能,但没有人效仿?这就是为什么我们不能拥有美好的事物
J
Jonathan Camenisch

这是一种对我来说似乎更清洁的方法。

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

$('form').click(function(event) {
  $(this).data('clicked',$(event.target))
});

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

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

if ($(this).data('clicked').is('[name=no_ajax]')) xhr.abort();

C
Community

根据 this link,Event 对象包含一个字段 Event.target,它:

返回一个字符串,该字符串表示启动事件的对象。

我刚刚创建了一个页面来测试该值是什么,它看起来好像该表示是针对表单本身,而不是针对单击的按钮。换句话说,Javascript 不提供确定单击按钮的功能。

至于 Dave Anderson 的 solution,在使用它之前在多个浏览器中测试它可能是一个好主意。有可能它可以正常工作,但我不能说任何一种方式。


target 返回整个表单。因此不幸的是,检测正确的提交按钮没有帮助。
我在我的回答中说了很多,@Hafenkranich。
Event.target 不是字符串。它是一个 EventTarget 对象,在本例中是提交的表单本身。
u
user1128563

一种干净的方法是在每个表单按钮上使用 click 事件。以下是一个带有保存、取消和删除按钮的 html 表单:

<form  name="formname" action="/location/form_action" method="POST">
<input name="note_id" value="some value"/>
<input class="savenote" type="submit" value="Save"/>
<input class="cancelnote" type="submit" value="Cancel"/>
<input class="deletenote" type="submit" value="Delete" />
</form> 

以下是jquery。我根据单击的按钮(“保存”或“删除”)将适当的“操作”发送到同一服务器功能。如果单击“取消”,我只需重新加载页面。

$('.savenote').click(function(){
   var options = {
       data: {'action':'save'}
   };
   $(this).parent().ajaxSubmit(options);
   });


$('.deletenote').click(function(){
   var options = {
       data: {'action':'delete'}
   };
   $(this).parent().ajaxSubmit(options);
   });


$('.cancelnote').click(function(){
   window.location.reload(true);
   return false;
   });

N
Nur Ilyas

表单的 SubmitEvent 有一个 submitter 属性。但是,截至目前,这在 Safari 上不起作用。

<form id="form">
    <button value="add" type="submit">Add</button>
    <button value="remove" type="submit">Remove</button>
</form>
let form = document.getElementById('form');

form.onsubmit = (event) => {
    e.preventDefault();
    console.log(e.submitter.type);
}

一种跨浏览器工作的不同方法。但是,您必须依赖 form 元素而不是 event 对象。这基本上在表单元素对象上添加了一个“提交者”属性,稍后可以在表单提交时引用该属性。

<form id="form">
    <button onclick="this.form.submitter = 'add'" type="submit">Add</button>
    <button onclick="this.form.submitter = 'remove'" type="submit">Remove</button>
</form>
let form = document.getElementById('form');

form.onsubmit = (event) => {
    e.preventDefault();
    console.log(form.submitter);
}

J
J. Bruni

我搜索并找到了几种使用 jQuery + AJAX 将提交按钮 name + value 发送到服务器的方法。我不是很喜欢他们...

最好的之一是这里提出的猎人解决方案!

但是我自己又写了一篇。

我想分享,因为它很好,并且根据我的需要,它也适用于通过 ajax 加载的表单(在 document.ready 之后):

$(document).on('click', 'form input[type=submit]', function(){
    $('<input type="hidden" />').appendTo($(this).parents('form').first()).attr('name', $(this).attr('name')).attr('value', $(this).attr('value'));
});

简单的!单击提交按钮时,将向表单添加一个隐藏字段,使用与提交按钮相同的 namevalue

编辑:下面的版本更容易阅读。此外,它还负责删除先前附加的隐藏字段(在两次提交相同表单的情况下,这在使用 AJAX 时是完全可能的)。

改进的代码:

$(document).on('click', 'form input[type=submit]', function(){
    var name   = $(this).attr('name');
    if (typeof name == 'undefined') return;
    var value  = $(this).attr('value');
    var $form  = $(this).parents('form').first();
    var $input = $('<input type="hidden" class="temp-hidden" />').attr('name', name).attr('value', value);
    $form.find('input.temp-hidden').remove();
    $form.append($input);
});

1+ 这为我做了。谢谢!
看起来这依赖于所有 <button/> 共享相同的 name 属性。我会使用一个类并在您的 .remove() 中引用它。
@binki:不,不是。无论如何,每个开发人员都可以根据自己的需要调整解决方案。
jsfiddle.net/binki/d8ecv 显示了我对 name 属性的意思。如果表单被重用并且包含具有不同名称的提交输入,那么旧的输入可能会使表单变得混乱。
现在我明白了……我会更新我的答案。 (事实上,我并没有太在意你的评论,因为你提到了 <button/> 元素,而代码中使用了 <input type="submit" />...)
u
user3126867

( 事件 )

function submForm(form,event){
             var submitButton;

             if(typeof event.explicitOriginalTarget != 'undefined'){  //
                 submitButton = event.explicitOriginalTarget;
             }else if(typeof document.activeElement.value != 'undefined'){  // IE
                 submitButton = document.activeElement;
             };

             alert(submitButton.name+' = '+submitButton.value)
}


<form action="" method="post" onSubmit="submForm(this, event); return false;">

R
Rudi Strydom

我确实尝试了提供的一些示例,但它们对我们的目的不起作用。

这是一个要展示的小提琴:http://jsfiddle.net/7a8qhofo/1/

我遇到了类似的问题,这就是我们在表单中解决问题的方式。

$(document).ready(function(){

    // Set a variable, we will fill later.
    var value = null;

    // On submit click, set the value
    $('input[type="submit"]').click(function(){
        value = $(this).val();
    });

    // On data-type submit click, set the value
    $('input[type="submit"][data-type]').click(function(){
        value = $(this).data('type');
    });

    // Use the set value in the submit function
    $('form').submit(function (event){
        event.preventDefault();
        alert(value);
        // do whatever you need to with the content
    });
});

K
Karishma Sukhwani

从事件对象中获取提交者对象

您可以在提交表单时简单地获取事件对象。从中获取提交者对象。如下:

$(".review-form").submit(function (e) {
        e.preventDefault(); // avoid to execute the actual submit of the form.

        let submitter_btn = $(e.originalEvent.submitter);
        
        console.log(submitter_btn.attr("name"));
}

我已在此答案中详细解释:(https://stackoverflow.com/a/66334184/11320178
如果您有任何疑问,请告诉我。


它在 Safari 中不起作用
你能告诉我你得到这个代码的错误或输出吗?
a
andres descalzo

您可以使用“event.originalEvent.x”和“event.originalEvent.y”尝试这种方式:

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
    <title>test</title>
</head>
<body>

    <form id="is_a_form">
        <input id="is_a_input_1" type="submit"><br />
        <input id="is_a_input_2" type="submit"><br />
        <input id="is_a_input_3" type="submit"><br />
        <input id="is_a_input_4" type="submit"><br />
        <input id="is_a_input_5" type="submit"><br />
    </form>

</body>
</html>
<script>
$(function(){

    $.fn.extend({
      inPosition: function(x, y) {

        return this.each(function() {

            try{
                var offset = $(this).offset();

                if ( (x >= offset.left) &&
                     (x <= (offset.left+$(this).width())) &&
                     (y >= offset.top) &&
                     (y <= (offset.top+$(this).height())) )
                {
                    $(this).css("background-color", "red");
                }
                else
                {
                        $(this).css("background-color", "#d4d0c8");
                }
                }
                catch(ex)
                {
                }

        });
      }
    }); 

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

        $("input[type='submit']").inPosition(ev.originalEvent.x ,ev.originalEvent.y);
        return false;

    });

});
</script>

“哎呀”?,有效,无效,有用,没用,...? , 我英语不好
@hunter 我如何多次支持您的评论?
M
Matchu

jQuery 似乎没有在提交事件中提供该数据。看起来你提出的方法是你最好的选择。


r
roland

只是另一种解决方案,因为没有其他解决方案符合我的要求。优点是可以检测到单击和按键(输入和空格)。

// Detects the Events
var $form = $('form');
$form.on('click keypress', 'button[type="submit"]', function (ev) {

    // Get the key (enter, space or mouse) which was pressed.
    if (ev.which === 13 || ev.which === 32 || ev.type === 'click') {

        // Get the clicked button
        var caller = ev.currentTarget;

        // Input Validation
        if (!($form.valid())) {
            return;
        }

        // Do whatever you want, e.g. ajax...
        ev.preventDefault();
        $.ajax({
            // ...
        })
    }
}

这对我来说效果最好。


佚名

使用更具体的事件处理程序和 JQuery,您的事件对象就是单击的按钮。如果需要,您还可以从此活动中获取委托表格。

$('form').on('click', 'button', function (e) {
  e.preventDefault();
  var
    $button = $(e.target),
    $form = $(e.delegateTarget);
  var buttonValue = $button.val();
});

该文档包含您入门所需的一切。 JQuery Doc


B
BabiBN

我写了这个对我有帮助的函数

var PupulateFormData= function (elem) {
    var arr = {};
    $(elem).find("input[name],select[name],button[name]:focus,input[type='submit']:focus").each(function () {
        arr[$(this).attr("name")] = $(this).val();
    });
    return arr;

};

然后使用

var data= PupulateFormData($("form"));

j
jimmont

在处理表单元素位于 shadowRoot 中的 Web 组件时,我采用了 Tobias Buschor 的优秀 polyfill,如下所示,通过导入的模块以下列方式工作。请注意,这只在常青客户端(edge、safari、chrome、firefox)中提供兼容性。此外,正如 Mikko Rantalainen 所指出的,这并没有遵循(我/我们可以在某个时候更新以遵循)https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-form-submit

if( !('SubmitEvent' in self && 'submitter' in SubmitEvent.prototype) ){
// polyfill SubmitEvent.submitter (a Safari issue as-of 2021)
// https://developer.mozilla.org/docs/Web/API/SubmitEvent
    const submitter = Symbol.for('submitter');
    Event[ submitter ] = null;
    const submitterSelector = 'input[type=submit], input[type=image], input[type=button], button';

    Object.defineProperty(Event.prototype, 'submitter', {
        get: function(){
            if('submit' === this.type){
                let node = Event[ submitter ];
                const form = this.target;
                if(!node || !form.contains(node)){
                    node = form.querySelector(submitterSelector);
                }
                // always return a node, default as though form.submit called
                return node || form;
            }
            return undefined;
        },
        set: function(value){
            if('submit' === this.type){
                this.submitter = value;
            }
        }
    });
    self.addEventListener('click', function polyfill_SubmitEvent_submitter_click(event){
        const node = event.composedPath()[0];
        const closest = node.closest?.(submitterSelector) ?? null;
        Event[ submitter ] = closest;
    }, true);
}

J
Jiffin

$(document).ready(function() { $( "form" ).submit(function (event) { // 获取提交按钮元素 let submit_button = event.handleObj; //提交按钮有点击使用的对象按钮 }); }


正如目前所写的那样,您的答案尚不清楚。请edit添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。您可以找到有关如何写出好答案的更多信息in the help center
M
Mario Petrovic

您可以获取以下 HTML 代码的按钮 id:

<form id="theForm" action="" method="POST">
  <button name="sbtn" id="sbtn" value="Hey button" type="submit">Submit</button>
</form>

使用以下 JavaScript(利用 .val() 属性):

$('#theForm').on('click', 'button', function (e) {
  e.preventDefault();
  var
    $button = $(e.target),
    $form = $(e.delegateTarget);
  var buttonValue = $button.val();
});

A
Abraham

没有jQuery

submit(e){
    console.log(e.nativeEvent.submitter)
}

A
AllQuestionsAreGood

我终于能够找到一个完整而简单的问题答案:如何从表单提交事件中获取导致提交的按钮?

我给你一个简单的例子:

代码 HTML:表单

<form id="myForm" enctype="multipart/form-data" method="post">

  ...
  all input, select, textarea ...
  ....

  <button id="bt1" value="add" type="submit">Add</button>
  <button id="bt2" value="back" type="submit">Back</button>
  <button id="bt3" value="remove" type="submit">Remove</button>
  <button id="bt4" value="register" type="submit">Register</button>
</form>

CODE JAVASCRIPT:事件监听器和动作

var myFctSubmit = function(event){
   var myTarget = event.target || event.srcElement;
   var myButton = event.originalEvent.submitter;

   var balise_form = $(myTarget).attr('id');
   var balise_button = $(myButton).attr('id');

   //Now you know the button and
   //you can apply the script you want...
   //here in this exemple :
   //balise_form = myForm
   //balise_button = {button that you click}

}

$('#myForm').bind('submit',myFctSubmit);

因此,此问题的解决方案是获取以下元素:

event.originalEvent.submitter

大家好运