当我禁用提交按钮以防止双击时,为什么我的表单没有发布?

时间:2022-11-24 08:54:41

Like every other web developer on the planet, I have an issue with users double clicking the submit button on my forms. My understanding is that the conventional way to handle this issue, is to disable the button immediately after the first click, however when I do this, it doesn't post.

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

I did do some research on this, god knows there's enough information, but other questions like Disable button on form submission, disabling the button appears to work. The original poster of Disable button after submit appears to have had the same problem as me, but there is no mention on how/if he resolved it.

我确实做了一些研究,上帝知道有足够的信息,但其他问题,如表单提交上的禁用按钮,禁用按钮似乎工作。提交后禁用按钮的原始海报似乎与我有同样的问题,但没有提及如何/如果他解决它。

Here's some code on how to repeat it (tested in IE8 Beta2, but had same problem in IE7)

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

My aspx code

我的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>

My cs code

我的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");
    }
}

Notice that when you click the button, a postback occurs, and the time is updated. But when you check the check box, the next time you click the button, the button is disabled (as expected), but never does the postback.

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

WHAT THE HECK AM I MISSING HERE???

我在这里想念的是什么?

Thanks in advance.

提前致谢。

10 个解决方案

#1


9  

I think you're just missing this tag:

我想你只是错过了这个标签:

UseSubmitBehavior="false"

Try it like this:

试试这样:

<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

说明

#2


6  

fallen888 is right, your approach doesn't work cross-browser. I use this little snippet to prevent double-click.

falling888是对的,你的方法不适用于跨浏览器。我使用这个小片段来防止双击。

#3


5  

UseSubmitBehavior="false" converts submit button to normal button (<input type="button">). If you don't want this to happen, you can hide submit button and immediately insert disabled button on its place. Because this happens so quickly it will look as button becoming disabled to user. Details are at the blog of Josh Stodola.

UseSubmitBehavior =“false”将提交按钮转换为普通按钮()。如果您不希望发生这种情况,可以隐藏提交按钮并立即在其位置插入禁用按钮。因为这种情况发生得太快,所以看起来按钮会被禁用给用户。详情请见Josh Stodola的博客。

Code example (jQuery):

代码示例(jQuery):

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

#4


4  

"Disabling" HTML controls doesn't always produce consistent behavior in all major browsers. So I try to stay away from doing that on the client-side, because (working with the ASP.NET model) you need to keep track of element's state on client and server in that case.

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

What I'd do is move button off the visible part of the window by switching the button's className to a CSS class that contains the following:

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

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

Now, what to put in place of the button?

现在,用什么代替按钮?

  1. Either an image that looks like a disabled button
  2. 一个看起来像禁用按钮的图像
  3. Or just plain text that says "Please wait..."
  4. 或者只是简单的文字说“请等待......”

And this can be done the same way but in reverse. Start with the element being hidden at page load and then switch to a visible className on form submit.

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

#5


2  

We use the following JQuery script, to disable all buttons (input type=submit and button), when one button is clicked.

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

We just included the script in a global JavaScript file, so we don't have to do remember anything when creating new buttons.

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

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

This script could easily be extended with a check for Page_ClientValidate().

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

#6


1  

document.getElementById('form1').onsubmit = function() {
    document.getElementById('btn').disabled = true;
};

#7


1  

This is the correct and simple way to do this:

这是执行此操作的正确且简单的方法:

It works in all browsers (unlike the accepted solution above).

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

Create a helper method in your application (say in a Utlity Namespace):

在您的应用程序中创建一个帮助器方法(比如在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

Now from the code behind of each of your web pages you can simply call:

现在,您可以通过每个网页的代码调用:

    Utility.PreventMultipleClicks(button1, page)

where button1 is the the button you want to prevent multiple clicks.

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

What this does is simply sets the on click handler to: this.disabled=true

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

and then appends the buttons own post back handler, so we get:

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

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

的onclick = “this.disabled =真”; __ doPostBack( 'ID $ ID', '');”

This does not break the default behaviour of the page and works in all browsers as expected.

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

Enjoy!

请享用!

#8


0  

For debugging purposes, what happens if you put an else clause against the if(chk.checked)?

出于调试目的,如果对if(chk.checked)放置else子句会发生什么?

#9


0  

Make sure that your javascript function returns true (or a value that would evaluate to boolean true), otherwise the form won't get submitted.

确保你的javascript函数返回true(或者一个值为boolean 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
}

#10


0  

FOR JQUERY USERS

对于评论用户

You will get into all sorts of problems trying to add javascript directly to the onClick event on ASP.NET buttons when using jQuery event listeners.

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

I found the best way to disable buttons and get the postback to work was to do something like this:

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

    $(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;
    });

Where ValidateForm is your custom validation function which returns true or false if your form validates client side.

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

And buttonID is the id of your button such as '#button1'

而buttonID是您的按钮的ID,例如'#button1'

#1


9  

I think you're just missing this tag:

我想你只是错过了这个标签:

UseSubmitBehavior="false"

Try it like this:

试试这样:

<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

说明

#2


6  

fallen888 is right, your approach doesn't work cross-browser. I use this little snippet to prevent double-click.

falling888是对的,你的方法不适用于跨浏览器。我使用这个小片段来防止双击。

#3


5  

UseSubmitBehavior="false" converts submit button to normal button (<input type="button">). If you don't want this to happen, you can hide submit button and immediately insert disabled button on its place. Because this happens so quickly it will look as button becoming disabled to user. Details are at the blog of Josh Stodola.

UseSubmitBehavior =“false”将提交按钮转换为普通按钮()。如果您不希望发生这种情况,可以隐藏提交按钮并立即在其位置插入禁用按钮。因为这种情况发生得太快,所以看起来按钮会被禁用给用户。详情请见Josh Stodola的博客。

Code example (jQuery):

代码示例(jQuery):

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

#4


4  

"Disabling" HTML controls doesn't always produce consistent behavior in all major browsers. So I try to stay away from doing that on the client-side, because (working with the ASP.NET model) you need to keep track of element's state on client and server in that case.

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

What I'd do is move button off the visible part of the window by switching the button's className to a CSS class that contains the following:

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

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

Now, what to put in place of the button?

现在,用什么代替按钮?

  1. Either an image that looks like a disabled button
  2. 一个看起来像禁用按钮的图像
  3. Or just plain text that says "Please wait..."
  4. 或者只是简单的文字说“请等待......”

And this can be done the same way but in reverse. Start with the element being hidden at page load and then switch to a visible className on form submit.

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

#5


2  

We use the following JQuery script, to disable all buttons (input type=submit and button), when one button is clicked.

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

We just included the script in a global JavaScript file, so we don't have to do remember anything when creating new buttons.

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

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

This script could easily be extended with a check for Page_ClientValidate().

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

#6


1  

document.getElementById('form1').onsubmit = function() {
    document.getElementById('btn').disabled = true;
};

#7


1  

This is the correct and simple way to do this:

这是执行此操作的正确且简单的方法:

It works in all browsers (unlike the accepted solution above).

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

Create a helper method in your application (say in a Utlity Namespace):

在您的应用程序中创建一个帮助器方法(比如在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

Now from the code behind of each of your web pages you can simply call:

现在,您可以通过每个网页的代码调用:

    Utility.PreventMultipleClicks(button1, page)

where button1 is the the button you want to prevent multiple clicks.

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

What this does is simply sets the on click handler to: this.disabled=true

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

and then appends the buttons own post back handler, so we get:

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

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

的onclick = “this.disabled =真”; __ doPostBack( 'ID $ ID', '');”

This does not break the default behaviour of the page and works in all browsers as expected.

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

Enjoy!

请享用!

#8


0  

For debugging purposes, what happens if you put an else clause against the if(chk.checked)?

出于调试目的,如果对if(chk.checked)放置else子句会发生什么?

#9


0  

Make sure that your javascript function returns true (or a value that would evaluate to boolean true), otherwise the form won't get submitted.

确保你的javascript函数返回true(或者一个值为boolean 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
}

#10


0  

FOR JQUERY USERS

对于评论用户

You will get into all sorts of problems trying to add javascript directly to the onClick event on ASP.NET buttons when using jQuery event listeners.

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

I found the best way to disable buttons and get the postback to work was to do something like this:

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

    $(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;
    });

Where ValidateForm is your custom validation function which returns true or false if your form validates client side.

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

And buttonID is the id of your button such as '#button1'

而buttonID是您的按钮的ID,例如'#button1'