【问题标题】:How To Determine Which Submit Button Was Pressed, Form onSubmit Event, Without jQuery [duplicate]如何确定按下了哪个提交按钮,表单 onSubmit 事件,没有 jQuery [重复]
【发布时间】:2011-04-04 09:31:40
【问题描述】:

我有一个带有两个提交按钮和一些代码的表单:

HTML:

<input type="submit" name="save" value="Save" />
<input type="submit" name="saveAndAdd" value="Save and add another" />

JavaScript:

form.onSubmit = function(evnt) {
    // Do some asyncrhnous stuff, that will later on submit the form
    return false;
}

当然,两个提交按钮完成不同的事情。有没有办法在onSubmit 中找出按下了哪个按钮,以便稍后我可以通过thatButton.click() 提交?

理想情况下,我不想修改按钮的代码,只需要一个具有此行为的纯 JavaScript 插件即可。

我知道 Firefox 有 evnt.explicitOriginalTarget,但我找不到其他浏览器的任何东西。

【问题讨论】:

    标签: javascript html


    【解决方案1】:
    <form onsubmit="alert(this.submitted); return false;">
        <input onclick="this.form.submitted=this.value;" type="submit" value="Yes" />
        <input onclick="this.form.submitted=this.value;" type="submit" value="No" />
    </form>
    

    jsfiddle 相同

    【讨论】:

    • 这个方案简单、优雅、易于实现;为什么有人会更喜欢 Peter Bailey 的解决方案,它非常繁琐并且需要 jquery(原始问题未指定),这超出了我的理解。
    • 如果表单是由用户按回车提交的,这将不起作用
    • @99Problems-Syntaxain'tone 因为输入不是屏幕上的提交按钮,根本不是要求?
    • 这是如何工作的?我不知道什么是“this.form.submited”。如何从按钮对象中访问表单?
    【解决方案2】:

    不在提交事件处理程序本身中,没有。

    但是您可以做的是向每个提交添加点击处理程序,这将通知提交处理程序哪些被点击了。

    这是一个完整的例子(为了简洁起见,使用 jQuery)

    <html>
    <head>
      <title>Test Page</title>
      <script src="http://code.jquery.com/jquery-latest.js"></script>
      <script type="text/javascript">
    
      jQuery(function($) {
          var submitActor = null;
          var $form = $('#test');
          var $submitActors = $form.find('input[type=submit]');
    
          $form.submit(function(event) {
              if (null === submitActor) {
                  // If no actor is explicitly clicked, the browser will
                  // automatically choose the first in source-order
                  // so we do the same here
                  submitActor = $submitActors[0];
              }
    
              console.log(submitActor.name);
              // alert(submitActor.name);
    
              return false;
          });
    
          $submitActors.click(function(event) {
              submitActor = this;
          });
      });
    
      </script>
    </head>
    
    <body>
    
      <form id="test">
    
        <input type="text" />
    
        <input type="submit" name="save" value="Save" />
        <input type="submit" name="saveAndAdd" value="Save and add another" />
    
      </form>
    
    </body>
    </html>
    

    【讨论】:

    • ...或者,您可以在点击冒泡时捕捉点击,方法是向表单本身添加一个 onclick 处理程序,检查点击的元素是否是提交按钮;在某些情况下,这可能会更简单。
    • @JeromeJ:编辑此答案以包含示例;希望同行评审将允许它通过。 (我会发布它作为我自己的答案,但问题已关闭)。
    • @Peter,如果您检查点击,当他们使用 Enter 键或其他方式“按下”提交按钮时会发生什么? (它仍然适用于 Chrome,但是)有标准行为吗?
    • 我不是 100% 了解当前的兼容性,但一般来说,如果点击实际上并不重要,我会说不要检查点击。
    • 原始问题没有提及或参考jquery。我们中的许多人不想使用 jquery。
    【解决方案3】:

    裸露的骨骼,但确认工作,例如:

    <script type="text/javascript">
    var clicked;
    function mysubmit() {
        alert(clicked);
    }
    </script>
    <form action="" onsubmit="mysubmit();return false">
        <input type="submit" onclick="clicked='Save'" value="Save" />
        <input type="submit" onclick="clicked='Add'" value="Add" />
    </form>
    

    【讨论】:

      【解决方案4】:

      上面所有的答案都很好,但我稍微整理了一下。

      此解决方案会自动将按下的提交按钮的名称放入操作隐藏字段中。页面上的javascript和服务器代码都可以根据需要检查动作隐藏字段值。

      解决方案使用jquery自动应用于所有提交按钮。

      <input type="hidden" name="action" id="action" />
      <script language="javascript" type="text/javascript">
          $(document).ready(function () {
              //when a submit button is clicked, put its name into the action hidden field
              $(":submit").click(function () { $("#action").val(this.name); });
          });
      </script>
      <input type="submit" class="bttn" value="<< Back" name="back" />
      <input type="submit" class="bttn" value="Finish" name="finish" />
      <input type="submit" class="bttn" value="Save" name="save" />
      <input type="submit" class="bttn" value="Next >>" name="next" />
      <input type="submit" class="bttn" value="Delete" name="delete" />
      <input type="button" class="bttn" name="cancel" value="Cancel" onclick="window.close();" />
      

      然后将这样的代码写入表单提交处理程序。

       if ($("#action").val() == "delete") {
           return confirm("Are you sure you want to delete the selected item?");
       }
      

      【讨论】:

      • 这取决于在提交表单之前处理的点击事件。会一直这样吗?对于在模式对话框中动态加载的表单,您必须使用委托处理程序并且必须附加它,以便它使用事件目标来确定哪个表单包含单击的元素并确保您的目标隐藏字段在里面那个表格。
      【解决方案5】:

      第一个建议:

      创建一个将引用单击的按钮的 Javascript 变量。让我们称之为 buttonIndex

      <input type="submit" onclick="buttonIndex=0;" name="save" value="Save" />
      <input type="submit" onclick="buttonIndex=1;" name="saveAndAdd" value="Save and add another" />
      

      现在,您可以访问该值。 0 表示点击了保存按钮,1 表示点击了 saveAndAdd 按钮。

      第二个建议

      我处理这个问题的方法是创建两个 JS 函数来处理两个按钮中的每一个。

      首先,确保您的表单具有有效的 ID。对于这个例子,我会说 ID 是“myForm”

      改变

      <input type="submit" name="save" value="Save" />
      <input type="submit" name="saveAndAdd" value="Save and add another" />
      

      <input type="submit" onclick="submitFunc();return(false);" name="save" value="Save" />
      <input type="submit" onclick="submitAndAddFunc();return(false);" name="saveAndAdd" value="Save and add 
      

      return(false) 将阻止您的表单提交实际处理,并调用您的自定义函数,您可以稍后在其中提交表单。

      那么你的函数将像这样工作......

      function submitFunc(){
          // Do some asyncrhnous stuff, that will later on submit the form
          if (okToSubmit) {
              document.getElementById('myForm').submit();
          }
      }
      function submitAndAddFunc(){
          // Do some asyncrhnous stuff, that will later on submit the form
          if (okToSubmit) {
              document.getElementById('myForm').submit();
          }
      }
      

      【讨论】:

      • 排序的。然后,我必须在每个提交函数中添加隐藏字段,其中一个具有 name="save" value="..." 等等,我正试图避免这种情况。不要误会我的意思,这是一个有效的解决方案。我只是在寻找更优雅的东西。
      • 隐藏字段?为了什么?
      • #2 不起作用 - 当您使用基于 DOM 的事件处理程序时,return 语句之后不会执行任何操作。因此,您对submitFunc()submitAndAddFunc() 的调用将永远不会触发。
      • 很好。颠倒了调用的顺序。
      【解决方案6】:

      OP 表示他不想修改按钮的代码。这是我可以使用其他答案作为指导提出的侵入性最小的答案。它不需要额外的隐藏字段,允许您保持按钮代码不变(有时您无权访问生成它的内容),并为您提供您在代码中的任何位置寻找的信息...哪个按钮用于提交表单。我还没有评估如果用户使用 Enter 键提交表单而不是单击会发生什么。

      <script language="javascript" type="text/javascript">
      
          var initiator = '';
          $(document).ready(function() {
              $(":submit").click(function() { initiator = this.name });
          });
      
      </script>
      

      然后,您可以在任何可能需要进行检查的地方访问“启动器”变量。希望这会有所帮助。

      ~斯潘基

      【讨论】:

        【解决方案7】:

        我使用 Ext,所以我最终这样做了:

        var theForm = Ext.get("theform");
        var inputButtons = Ext.DomQuery.jsSelect('input[type="submit"]', theForm.dom);
        var inputButtonPressed = null;
        for (var i = 0; i < inputButtons.length; i++) {
            Ext.fly(inputButtons[i]).on('click', function() {
                inputButtonPressed = this;
            }, inputButtons[i]);
        }
        

        然后到了提交的时候我就提交了

        if (inputButtonPressed !== null) inputButtonPressed.click();
        else theForm.dom.submit();
        

        等等,你说。如果你不小心,这将循环。所以,onSubmit 有时必须返回 true

        // Notice I'm not using Ext here, because they can't stop the submit
        theForm.dom.onsubmit = function () {
            if (gottaDoSomething) {
                // Do something asynchronous, call the two lines above when done.
                gottaDoSomething = false;
                return false;
            }
            return true;
        }
        

        【讨论】:

          【解决方案8】:

          为什么不遍历输入,然后为每个输入添加 onclick 处理程序?

          您不必在 HTML 中执行此操作,但您可以为每个按钮添加一个处理程序,例如:

          button.onclick = function(){ DoStuff(this.value); return false; } // return false; so that form does not submit
          

          然后您的函数可以根据您传递的任何值“做事”:

          function DoStuff(val) {
              if( val === "Val 1" ) {
                  // Do some stuff
              }
              // Do other stuff
          }
          

          【讨论】:

          • 我能想到的唯一方法是在按下最后一个输入按钮的情况下设置某种全局变量。这不是一个坏主意。
          • 好的。但是,我想我不确定你到底想做什么。
          猜你喜欢
          • 2011-04-02
          • 2011-08-09
          • 1970-01-01
          • 2014-02-25
          • 1970-01-01
          • 1970-01-01
          • 2013-10-03
          • 2012-10-02
          • 1970-01-01
          相关资源
          最近更新 更多