【问题标题】:Prevent double clicking asp.net button防止双击asp.net按钮
【发布时间】:2014-10-01 17:39:43
【问题描述】:

我知道有人问过这个问题,但没有一个答案适用于我的项目。

我有一个按钮,点击后会调用 API,因此会有 1 秒的延迟。

我已经尝试了几件事,但没有任何效果。

btnSave.Attributes.Add("onclick", " this.disabled = true; " + ClientScript.GetPostBackEventReference(btnSave, null) + ";");

即使这样也无济于事。

【问题讨论】:

标签: asp.net button


【解决方案1】:

防止双击。请在您的aspx页面中添加以下代码。

<script type="text/javascript" language="javascript">

   Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
   function BeginRequestHandler(sender, args) { var oControl = args.get_postBackElement(); oControl.disabled = true; }

</script>

【讨论】:

  • 迄今为止最好的解决方案 :-)
  • 您能解释一下这是如何工作的吗?这是如何与btnSave 挂钩的?
  • 不起作用。我得到Error: 'Sys' is undefined ...我需要在aspx页面中的什么地方添加这个脚本?
  • @nu everest:必须在客户端 (javascript) 上禁用按钮,因为服务器端的禁用速度不够快。在服务器端代码禁用该按钮之前,用户可以单击该按钮几次。 (“get_postBackElement” - 获取启动异步回发的回发元素。)
  • 如果你在使用这个时得到Error: 'Sys' is undefined,那是因为你需要一个ScriptManager在页面上。
【解决方案2】:

您可以使用此代码防止双击:

Me.btnSave.Attributes.Add("onclick", "this.disabled=true;")
Me.btnSave.UseSubmitBehavior = False

所以你可以使用btnSave_Click 来调用你的API。

通常我的Page 中有很多Validators:设置Validator.SetFocusOnError = True 如果验证失败,我可以运行此代码以重新启用保存按钮。

Me.YourControl.Attributes.Add("onfocus", Me.btnSave.ClientID & ".removeAttribute('disabled');")

【讨论】:

  • 它只在第一个之后有效,我有另一个按钮,上面写着“添加另一个”,在我点击它之后它有效,但在第一个之前无效?
  • 对不起,我不明白。
  • 很好的解决方案。我通过在 .aspx 页面上添加 JavaScript 以在单击时禁用按钮来实现这一点。我在控件本身上添加了UseSubmitBehavior="false"。对我来说达到了同样的效果,而不依赖于后面的代码。
【解决方案3】:

防止双击。请在您的aspx页面中添加以下代码

<script type = "text/javascript">
function DisableButton() {
document.getElementById("<%=Button1.ClientID %>").disabled = true;
}
window.onbeforeunload = DisableButton;
</script>

【讨论】:

  • 虽然这可能会有所帮助,但请不要只发布代码而没有解释我们正在查看的内容。
【解决方案4】:

此解决方案简单有效。在您的按钮上包含以下代码:

OnClientClick="return CheckDouble();"

无论你想要你的 JavaScript 在哪里 - 例如。在页面底部:

<script type="text/javascript">
   var submit = 0;
   function CheckDouble() {
     if (++submit > 1) {
     alert('This sometimes takes a few seconds - please be patient.');
     return false;
   }
 }
 </script>

【讨论】:

  • 这很有效,因为它会通知用户并有助于打破习惯。当警报对话框启动时,Windows 会发出小小的“叮”声。 :)
  • 漂亮,简单易懂...提醒信息很不错!
  • 它工作正常,但服务器验证不像必填字段验证等那样触发
  • 我添加了这个,它确实显示了消息,但仍然在服务器端触发了按钮单击事件。
  • 当您的按钮是提交时,我不这样做,因为它会导致“提交”变量重置为零。我可能对此并不正确,但无论哪种方式,它都不适合我。
【解决方案5】:

上述大多数建议都对我不起作用。 tezzo 的工作如下:

Me.btnSave.Attributes.Add("onclick", "this.disabled=true;")
Me.btnSave.UseSubmitBehavior = False

仍然更简单,而不是在代码隐藏中使用上述内容,只需使用以下内容:

   <asp:Button ID="btnSave" runat="server" Text="Save" 
      UseSubmitBehavior="false"
      OnClientClick="this.disabled='true';" 
   </asp:button>

UseSubmitBehavior="false" 是关键。

【讨论】:

  • 这是最干净的!想知道为什么你必须设置 UseSubmitBehavior="false" 但是为什么不返回 true 做回发
  • 第二种方法是最简单的,它适合大多数场景。感谢您的回答!
【解决方案6】:

一开始我的解决方案是这样的:

<script>
function disableButton(btn) {
    setTimeout(function () { btn.disabled = true; }, 20);
    return true;
}
</script>
<asp:Button runat="server" ID="btnSave" Text="Save" OnClick="btnSave_Click" OnClientClick="return disableButton(this);" />

如果没有 setTimeout,按钮将立即被禁用,然后不会触发 OnClick 事件。这种方法的缺点是,如果某些验证失败或发生某些错误,将无法再访问 Save 按钮。

所以我不认为禁用按钮是一个好的解决方案,并提出另一个解决方案:

     function disableButton(btn) {
        if (btn.hasclicked) return false;
        btn.hasclicked = 1;
        btn.onmouseenter = function () { this.hasclicked = 0; };
        return true;
    }

但是我的同事指出,如果post处理很慢,在它完成之前,用户仍然可以通过leave-enter-click按钮执行双重postback。所以我想出了另外两个解决方案:

  1. 在提交表单之前从客户端运行验证。但是如果您的页面包含多个 ValidationGroup,则表示应该使用传入的 ValidationGroup 参数多次调用以下 Page_ClientValidate():例如Page_ClientValidate("group1"):

function disableButton(btn) {
  if (Page_ClientValidate) {
    Page_ClientValidate();
    if (!Page_IsValid) {
      btn.setAttribute("btnClicked", "n");
      return true;
    }
  }
  if (btn.getAttribute("btnClicked") == "y") {
    return false;
  } else {
    btn.setAttribute("btnClicked", "y");
    return true;
  }
}
  1. 由于ASP.NET在一个页面中只有一个表单(不是ASP.NET MVC),我们也可以让表单的onsubmit客户端事件来拦截双击:

    function disableButton(btn) {
    $("form").submit(function () {
        if (btn.getAttribute("btnClicked") == "y") 
            return false;
        else 
            btn.setAttribute("btnClicked", "y");
            return true;
    });}
    

    我会要求 QA 测试这两种方法(后期编辑:QA 已经证明使用这种方法非常危险。详情请参考我的以下 cmets )。

【讨论】:

  • 我们的 QA 测试证明不能使用第二种方法(在表单提交点检查的最后一种方法),因为它会使 ASP.NET 验证机制完全不起作用。它不仅会绕过客户端的验证机制,还会使您的服务器端验证始终为 Page.IsValid == true。使用这种方法很糟糕。永远不要使用它!
  • Page_ClientValidate 在 DoPostbackWithOptions 中,如果提交按钮在 UserControl 中,那么选项 1 也可能导致问题,具体取决于控件所在的页面和设置验证的方式以及 Page_ClientValidate 是否已经存在叫。即使您通过了验证组。在服务器端使用一次性使用令牌可能会更好,这样队列中的后续请求就不会被使用的令牌兑现
【解决方案7】:

试试这个方法,这是一个可行的解决方案:

对于所有浏览器,包括不支持js的Opera Mobile浏览器,意味着您的表单在该类型的浏览器中不会被阻止。

在 Page_load() 方法中添加这个:

BtnID.Attributes.Add("onclick", "if(typeof (Page_ClientValidate) === 'function' && !Page_ClientValidate()){return false;} this.disabled = true;this.value = 'Working...';" + ClientScript.GetPostBackEventReference(BtnID, null) + ";");

【讨论】:

    【解决方案8】:

    这是我发现在所有情况下都有效的方法。

    <form id="form1" runat="server">
    <asp:Button ID="Button1" runat="server" Text="Button1" OnClick="Button1_Clicked" />
    <asp:Button ID="Button2" runat="server" Text="Button2" />
    </form>
    
    Now here’s the short JavaScript snippet that will disable the button as soon as it is clicked so that when PostBack occurs the button cannot be clicked again.
    <script type = "text/javascript">
    function DisableButton() {
        document.getElementById("<%=Button1.ClientID %>").disabled = true;
    }
    window.onbeforeunload = DisableButton;
    </script>
    
    The above script disables the ASP.Net Button as soon as the page is ready to do a PostBack or the ASP.Net form is submitted.
    But in cases you might want to disable all Buttons and Submit Buttons on the page hence for such cases I have created another function which disables all Buttons and Submit buttons whenever there’s a PostBack or form submission
    <script type = "text/javascript">
    function DisableButtons() {
        var inputs = document.getElementsByTagName("INPUT");
        for (var i in inputs) {
            if (inputs[i].type == "button" || inputs[i].type == "submit") {
                inputs[i].disabled = true;
            }
        }
    }
    window.onbeforeunload = DisableButtons;
    </script>
    

    【讨论】:

      猜你喜欢
      • 2017-05-31
      • 1970-01-01
      • 2011-07-08
      • 2018-06-14
      • 2015-10-17
      • 2010-09-08
      • 2022-01-21
      • 2011-09-11
      • 1970-01-01
      相关资源
      最近更新 更多