简体   繁体   English

防止双击导致在 HTML 表单中重复提交

[英]Prevent double clicks resulting in double submission of in an HTML forms

My problem was simple: I got to work on an already 5 years old web application with heavy forms and multiple buttons and links everywhere on the pages.我的问题很简单:我必须在一个已经有 5 年历史的 Web 应用程序上工作,该应用程序具有繁重的表单以及页面上随处可见的多个按钮和链接。 And we encountered trouble because a lot of our users were double clicking on buttons and links, often ending in actual double submissions of forms.我们遇到了麻烦,因为我们的很多用户都在双击按钮和链接,结果往往是实际提交了两次表单。

I am aware of most solutions usually given to peopole asking for such problems, like saying " for any button on the page, make it being disabled = true after the first click ".我知道大多数解决方案通常提供给要求此类问题的人,例如说“对于页面上的任何按钮,在第一次点击后使其被禁用 = 真”。 Some people also advice to use the dblclick event, ignoring that it is thrown only when there are two click events coming in a short time - meaning that once the dblclick event has been fired it is already too late because two clicks have already occurred.有些人还建议使用dblclick事件,忽略它只有在短时间内有两个点击事件时才会抛出 - 这意味着一旦dblclick事件被触发,就已经太晚了,因为已经发生了两次点击。 Same goes to the preventDefault() method, which mechanics does not addresses the problem. preventDefault() 方法也是如此,该方法并未解决该问题。

But as for the disable on click strategy, I just can't refactor the code of every single page of the application to put onclick handlers on the buttons and links.但是对于禁用单击策略,我无法重构应用程序的每个页面的代码以将onclick处理程序放在按钮和链接上。 Plus, most of them already have onclick handlers attached meaning that I won't be able to search and replace or anything like this.另外,它们中的大多数已经onclick处理程序,这意味着我将无法搜索和替换或类似的东西。 And I also don't want to make a jQuery request on every page load that would add a new click event handler on every button and link of the page.而且我也不想在每个页面加载时发出一个 jQuery 请求,这会在页面的每个按钮和链接上添加一个新的点击事件处理程序。 That would cost CPU resources and not be efficient anyway because there are some buttons that trigger popups rather than submitting forms and those must be clickable several times, and there are other examples of this kind.这会消耗 CPU 资源并且效率不高,因为有一些按钮会触发弹出窗口而不是提交表单,而且这些按钮必须可以多次点击,还有其他类似的例子。

What I am looking for is a simple and generic way to tell the Web Browser "When there is a double-click anywhere on the page, ignore the second click".我正在寻找的是一种简单而通用的方法来告诉 Web 浏览器“当在页面上的任何地方双击时,忽略第二次单击”。 I really don't understand how come it is not already possible to do so.我真的不明白为什么现在还不可能这样做。 Most probably because when you find yourself in such situation you are already far from the lines of the good practices but this is not my fault and I have a problem to address.很可能是因为当你发现自己处于这种情况时,你已经远离良好实践的界限,但这不是我的错,我有一个问题要解决。

I finally found quite a simple way to solve the problem that nobody told me about (too simple?).我终于找到了一个很简单的方法来解决没人告诉我的问题(太简单了?)。 The solution was to use an invisible layer that will occupy all the window, but be disabled by default.解决方案是使用一个将占据所有窗口的不可见层,但默认情况下是禁用的。 You can declare it this way:你可以这样声明:

<div id="prevent_dbclick" style="z-index: 1300; border: 0 none; top: 0px; left: 0px; margin: 0px; padding: 0px; width: 100%; height: 100%; opacity: 0; position: fixed; display: none;">500</div>

Now you will also need this Javascript function:现在你还需要这个 Javascript 函数:

function disableDbClick(){
    jQuery(window).click(function(){
        var prevDbDiv = jQuery("#prevent_dbclick");
        prevDbDiv.show(); 
        setTimeout(function(){
            prevDbDiv.hide();
        }, prevDbDiv.html());       
    });
}
window.onload = disableDbClick;

Note that I used jQuery for simplification but if your project don't use jQuery you can easily work it around.请注意,我使用 jQuery 进行简化,但如果您的项目不使用 jQuery,您可以轻松地解决它。

Now just call the function once the page is loaded.现在只需在页面加载后调用该函数。 The way it works is very simple: whenever there is a click somewhere on the page, the invisible layers comes over the page for 500ms then fade away and any click event in the interval will hit the layer and not the buttons or links, effectively preventing a double submission on a double click.它的工作方式非常简单:每当页面上的某处点击时,不可见的图层会在页面上方停留 500 毫秒然后消失,间隔内的任何点击事件都会击中图层而不是按钮或链接,有效防止双击提交。 Once the delay is expired people are free to click anywhere again.一旦延迟到期,人们可以自由地再次点击任何地方。

The 500ms delay was chosen since it is the delay that Windows use to differentiate a double-click from two successive clicks.之所以选择 500 毫秒延迟,是因为它是 Windows 用来区分双击和两次连续点击的延迟。 I did not hardcoded it in the javascript code because I wanted to be able to change it via a property of the application.我没有在 javascript 代码中对其进行硬编码,因为我希望能够通过应用程序的属性更改它。

Hope this will help.希望这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM