【问题标题】:Determining which submit button was clicked from jQuery/JavaScript [duplicate]确定从 jQuery/JavaScript 中单击了哪个提交按钮 [重复]
【发布时间】:2011-08-09 14:33:58
【问题描述】:

我正在从我没有编写的 PHP 应用程序中 ajaxifying 一些表单。为此,我想出了这个聪明的解决方案:

jQuery("form").submit(function(event) {
    // get some values from elements on the page:
    var the_form = jQuery(this);
    var data = the_form.serialize();
    var url = the_form.attr( 'action' );
    var button = event.originalEvent.explicitOriginalTarget;

    data = data + "&" + button.name + "=" + button.value;

    // Send the data using post and put the results in a div
    jQuery.post( url, data, function() {
        //Do something crazy
    });

    // stop form from submitting normally
    if (event.preventDefault) 
    { 
        event.preventDefault(); 
    } 
    else 
    {
        event.returnValue = false; 
    }
});

效果很好。我欣喜若狂地走了。问题是,我无意中使用了仅 Mozilla/Gecko 属性来确定单击了哪个按钮。 (event.originalEvent.explicitOriginalTarget) 这意味着这只适用于 Firefox。 :-(

所有这些都是必要的,因为我正在扩充的网络应用程序依赖于发布数据中的按钮名称/值来正确处理表单。所以,简单来说我的问题是:

确定在 jQuery 的提交事件中单击了哪个按钮的最佳跨浏览器方法是什么?

编辑: 这是我的解决方案。

jQuery("some selector that targets your form").find(":submit").click(function(event) {
    // get some values from elements on the page:
    var the_form = jQuery(this).parents("form");
    var data = the_form.serialize();
    var url = the_form.attr( 'action' );
    var button = event.target;

    data = data + "&" + button.name + "=" + button.value;

    // Send the data using post and put the results in a div
    jQuery.post( url, data, function() {
        //Do something crazy
    });

    // stop form from submitting normally
    if (event.preventDefault) 
    { 
        event.preventDefault(); 
    } 
    else 
    {
        event.returnValue = false; 
    }
});

【问题讨论】:

  • +1 包括您的最终解决方案。对我帮助很大。
  • 但是你不是在处理提交事件,而是在你的例子中点击事件,或者我错过了什么?

标签: javascript jquery cross-browser


【解决方案1】:

看到这个问题:Crossbrowser equivalent of explicitOriginalTarget event parameter

您将不得不将事件侦听器附加到按钮而不是表单,以便获得一种可靠的方法来确定哪个触发了提交。

【讨论】:

  • 感谢您的反馈,Greg...我想过切换到这种方法,但我觉得它很乱。我宁愿不要尝试预测可能导致表单提交的每个元素,如果我不需要的话,也可以将事件附加到它上面。似乎 jQuery/JavaScript/浏览器应该支持的东西。
  • 嗯,你得到的结果就是功能应该是什么。您要求的是由表单触发的事件,而不是由按钮触发的事件。该表单侦听按钮的事件,然后触发它自己的事件。在这种情况下,正确的做法是让按钮触发一个事件,然后让您拦截该事件并触发表单。
  • 好吧,我同意...你是对的。谢谢;)
【解决方案2】:

http://api.jquery.com/event.target/

jquery.event.target 应该可以工作,因为它已针对大多数浏览器进行了规范化。

jquery.event.currentTarget 可用于检索事件冒泡链中的当前项。

编辑—— 经过一些反思和@greg的建议: 我已经发布了一个代码 sn-p on jsfiddle

【讨论】:

  • event.target 是表单...不是触发提交的按钮。
  • (并且 event.target.currentTarget 是未定义的。event.currentTarget 也是形式)
  • 我看到我忽略了事件监听器——我假设你在听按钮然后提交表单——我的错。正如@greg 提到的,认为点击按钮会更好读。
【解决方案3】:

使用点击处理程序提交表单是有问题的,因为您不能使用提交事件处理程序进行验证(几乎所有验证器插件都会这样做)。此外,当您不使用 AJAX 发布时,如果在单击事件而不是提交事件中禁用提交按钮,则在某些浏览器中可能会产生奇怪的效果。

jQuery.Form 解决这个问题的方法是设置一个点击处理程序来存储被点击的按钮(然后用一个小的超时清除它),并使用提交处理程序通过 AJAX 实际发送表单内容。

【讨论】:

    【解决方案4】:

    这是我用来用 jQuery “ajaxify”我的表单的一个函数。

    function ajaxifyForm(form, callback)
    {
        var clicked
    
        form.find("button").click(function()
        {
            if (clicked != null) clicked.removeAttr("data-clicked")
            clicked = $(this)
            $(this).attr("data-clicked", 1)
        })
    
        form.submit(function(event)
        {
            var data = {}
            var name = ""
    
            form.find(":input").each(function()
            {
                var input = $(this)
    
                if (!(name = input.attr("name"))) return
    
                switch (input.attr("type"))
                {
                    case "radio":
                    case "checkbox":
                        if (input.attr("checked")) data[name] = input.val()
                        break
                    case "submit":
                        if (input.attr("data-clicked")) data[name] = input.val()
                        break
                    default:
                        data[name] = input.val()
                }
            })
    
            $.ajax({
                url: form.attr("action"),
                success: function(data)
                {
                    if (typeof callback == "function") callback("success")
                },
                error: function()
                {
                    if (typeof callback == "function") callback("error")
                },
                data: data,
                type: form.attr("method")
            })
    
            return false
        })
    
        return form
    }
    

    【讨论】:

      猜你喜欢
      • 2014-02-25
      • 1970-01-01
      • 1970-01-01
      • 2011-04-04
      • 2012-03-01
      • 2014-07-15
      • 2013-03-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多