【问题标题】:Why doesn't my form post when I disable the submit button to prevent double clicking?当我禁用提交按钮以防止双击时,为什么我的表单没有发布?
【发布时间】:2010-09-28 20:59:09
【问题描述】:

与地球上所有其他 Web 开发人员一样,我遇到了用户双击表单上的提交按钮的问题。我的理解是,处理此问题的常规方法是在第一次单击后立即禁用按钮,但是当我这样做时,它不会发布

我确实对此进行了一些研究,上帝知道有足够的信息,但其他问题,如Disable button on form submission,禁用按钮似乎有效。 Disable button after submit 的原始发帖人似乎和我有同样的问题,但没有提到他是如何解决的。

这是一些关于如何重复它的代码(在 IE8 Beta2 中测试,但在 IE7 中遇到了同样的问题)

我的aspx代码

<%@ Page Language="C#" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<script language="javascript" type="text/javascript">
    function btn_onClick()
    {
        var chk = document.getElementById("chk");
        if(chk.checked)
        {
            var btn = document.getElementById("btn");
            btn.disabled = true;
        }
    }
</script>
<body>
    <form id="form1" runat="server">
        <asp:Literal ID="lit" Text="--:--:--" runat="server" />
        <br />
        <asp:Button ID="btn" Text="Submit" runat="server" />
        <br />
        <input type="checkbox" id="chk" />Disable button on first click
    </form>
</body>
</html>

我的cs代码

using System;

public partial class _Default : System.Web.UI.Page 
{
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        btn.Click += new EventHandler(btn_Click);
        btn.OnClientClick = "btn_onClick();";
    }

    void btn_Click(object sender, EventArgs e)
    {
        lit.Text = DateTime.Now.ToString("HH:mm:ss");
    }
}

请注意,当您单击按钮时,会发生回发,并且时间会更新。但是当您选中该复选框时,下次单击该按钮时,该按钮将被禁用(如预期的那样),但永远不会回发。

我到底在想什么???

提前致谢。

【问题讨论】:

    标签: asp.net javascript client-side double-submit-prevention


    【解决方案1】:

    我认为你只是缺少这个标签:

    UseSubmitBehavior="false"
    

    试试这样:

    <asp:Button ID="btnUpdate" runat="server" UseSubmitBehavior="false" OnClientClick="if(Page_ClientValidate()) { this.disabled = true; } else {return false;}" Text = "Update" CssClass="button" OnClick="btnUpdate_Click" ValidationGroup="vgNew"/>
    

    Explanation

    【讨论】:

    • 谢谢,这确实有效。但是在 UseSubmitBehaviour 关闭默认浏览器表单发布并使用 ASP.NET 表单发布的地方,我有点担心 MS 特定技术而不是传统的做事方式。你知道使用这个有什么影响吗?再次感谢
    • @JohnMacIntyre - 对不起,您担心 microsoft 在 asp.net 控件中的特定技术?这似乎有点愚蠢,不是吗? asp.net 是微软特有的。
    【解决方案2】:

    fallen888 是对的,你的方法不能跨浏览器工作。我使用this little snippet 来防止双击。

    【讨论】:

      【解决方案3】:

      UseSubmitBehavior="false" 将提交按钮转换为普通按钮 (&lt;input type="button"&gt;)。如果您不希望这种情况发生,您可以隐藏提交按钮并立即在其位置插入禁用按钮。因为这种情况发生得如此之快,它看起来就像按钮被用户禁用。详情在the blog of Josh Stodola

      代码示例(jQuery):

      $("#<%= btnSubmit.ClientID %>").click(function()
      {
        $(this)
          .hide()
          .after('<input type="button" value="Please Wait..." disabled="disabled" />');
      });
      

      【讨论】:

      • 这个解决方案对我们很有效......尤其是当您需要输入值仍包含在表单中时。谢谢!
      【解决方案4】:

      “禁用”HTML 控件并不总是在所有主要浏览器中产生一致的行为。所以我尽量避免在客户端这样做,因为(使用 ASP.NET 模型)在这种情况下,您需要跟踪客户端和服务器上元素的状态。

      我要做的是通过将按钮的 className 切换为包含以下内容的 CSS 类来将按钮移出窗口的可见部分:

      .hiddenButton
      {
        position: absolute;
        top: -1000px;
        left: -1000px;
      }
      

      现在,用什么代替按钮?

      1. 看起来像禁用按钮的图像
      2. 或者只是显示“请稍候...”的纯文本

      这可以以相同的方式完成,但相反。从页面加载时隐藏的元素开始,然后在表单提交时切换到可见的 className。

      【讨论】:

        【解决方案5】:

        我们使用以下 JQuery 脚本来禁用所有按钮(输入类型=提交和按钮),当点击一个按钮时。

        我们只是将脚本包含在一个全局 JavaScript 文件中,因此在创建新按钮时无需记住任何内容。

        $(document).ready(function() {
            $(":button,:submit").bind("click", function() {
                setTimeout(function() {
                    $(":button,:submit").attr("disabled", "true");
                }, 0);
            });
        });
        

        通过检查 Page_ClientValidate() 可以轻松扩展此脚本。

        【讨论】:

          【解决方案6】:
          document.getElementById('form1').onsubmit = function() {
              document.getElementById('btn').disabled = true;
          };
          

          【讨论】:

          • 这不起作用,是用户要求修复的代码。 -1
          • 不,这是在表单的 onsubmit 上,而不是在按钮的 onclick 上。这样它将提交表单。但是感谢您的反对
          【解决方案7】:

          这是正确且简单的方法:

          它适用于所有浏览器(与上面公认的解决方案不同)。

          在您的应用程序中创建一个辅助方法(例如在 Utlity 命名空间中):

              Public Shared Sub PreventMultipleClicks(ByRef button As System.Web.UI.WebControls.Button, ByRef page As System.Web.UI.Page)
                  button.Attributes.Add("onclick", "this.disabled=true;" + page.ClientScript.GetPostBackEventReference(button, String.Empty).ToString)
              End Sub
          

          现在您可以从每个网页背后的代码中调用:

              Utility.PreventMultipleClicks(button1, page)
          

          其中 button1 是您要防止多次点击的按钮。

          这只是将点击处理程序设置为:this.disabled=true

          然后附加按钮自己的回发处理程序,所以我们得到:

          onclick="this.disabled=true";__doPostBack('ID$ID','');"

          这不会破坏页面的默认行为,并且可以在所有浏览器中按预期工作。

          享受吧!

          【讨论】:

          • 应避免将javascript添加到html中的onClick按钮
          【解决方案8】:

          JQUERY 用户

          在使用 jQuery 事件侦听器时,尝试将 javascript 直接添加到 ASP.NET 按钮上的 onClick 事件时会遇到各种问题。

          我发现禁用按钮并使回发工作的最佳方法是执行以下操作:

              $(buttonID).bind('click', function (e) {
          
                  if (ValidateForm(e)) {
          
                      //client side validation ok!
                      //disable the button:
                      $(buttonID).attr("disabled", true);
          
                      //force a postback:
                      try {
                          __doPostBack($(buttonID).attr("name"), "");
                          return true;
                      } catch (err) {
                          return true;
                      }
          
                  }
                  //client side validation failed!
                  return false;
              });
          

          ValidateForm 是您的自定义验证函数,如果您的表单验证客户端,则返回 true 或 false。

          buttonID是你的按钮的id,比如'#button1'

          【讨论】:

            【解决方案9】:

            出于调试目的,如果在 if(chk.checked) 中添加 else 子句会发生什么?

            【讨论】:

            • 嗨 Neil,我不确定我是否关注了你,但如果你建议我重新启用该按钮,它不会与一个简单的 else 一起工作,因为一旦它被禁用,它就不能被点击.我需要创建一个复选框单击事件来重新启用它,并且我想让事情尽可能简单。你是这个意思吗?
            • 不,我想知道它不起作用的原因是不是因为 chk,checked 可能没有返回 true,因此按钮没有被禁用。
            • 哦,好的。不,它肯定会禁用按钮,但不会提交帖子。再次感谢。
            【解决方案10】:

            确保您的 javascript 函数返回 true(或将评估为布尔值 true 的值),否则表单将不会被提交。

            function btn_click()
            var chk = document.getElementById("chk");
                if(chk.checked)
                {
                        var btn = document.getElementById("btn");
                        btn.disabled = true;
                        return true;   //this enables the controls action to propagate
                }
                else    return false;  //this prevents it from propagating
            }
            

            【讨论】:

            • 感谢 tj111,但我不认为事件冒泡被中断,因为它会回发直到我检查按钮。
            • 我遇到了同样的问题,我的第一次尝试就是这个解决方案。但是,它在 IE 上不起作用。我不得不采用 Vatos 解释的解决方案,即提交表单而不是单击按钮。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-07-08
            • 1970-01-01
            • 2020-03-31
            • 2021-10-13
            • 1970-01-01
            • 2011-12-12
            相关资源
            最近更新 更多