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

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

问题描述:

我的问题很简单:我必须在一个已有5年历史的Web应用程序上工作,这些应用程序具有繁重的表单和多个按钮,并且链接到页面上的任何地方。而且我们遇到了麻烦,因为我们的许多用户双击按钮和链接,通常以实际的双重提交形式结束。防止双击导致HTML表单中的双重提交

我知道大多数解决方案通常都是针对这种问题的peopole,比如说:“用于页面上的任何按钮,使其在第一次点击后被禁用= true”。有些人还建议使用dblclick事件,忽略只有在短时间内发生两个点击事件时才抛出它 - 这意味着一旦触发事件已经太晚了,因为已经发生了两次点击。与preventDefault()方法一样,该方法不能解决问题。

但是,至于禁用点击策略,我不能重构应用程序的每一个页面的代码,以将onclick处理程序放在按钮和链接上。另外,他们中的大多数已经有onclick处理程序附加,这意味着我将无法搜索和替换或类似的东西。而且我也不想在每个页面加载时发出一个jQuery请求,这会在页面的每个按钮和链接上添加一个新的点击事件处理程序。这会花费CPU资源,而且无论如何效率都不高,因为有些按钮会触发弹出窗口而不是提交表单,而且这些按钮必须可以多次点击,还有其他类似的例子。

我在寻找的是一种简单而通用的方式来告诉Web浏览器“当双击页面上的任何地方,忽略第二次点击”。我真的不明白为什么不可能这样做。最有可能的原因是,当你发现自己处于这种状况时,你已经远离良好实践,但这不是我的错,我有一个问题需要解决。

我终于找到了一个相当简单的方法来解决没人告诉我的问题(太简单了?)。解决方案是使用将占据所有窗口的不可见层,但默认情况下是禁用的。你可以声明这样说:

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

现在,你也需要这样的JavaScript函数:

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

请注意,我用的jQuery为了简化,但如果您的项目不使用jQuery,你可以轻松地工作它周围。

现在只需在页面加载后调用函数。它的工作方式非常简单:只要在页面上某处点击,不可见图层就会在页面上超过500毫秒,然后消失,并且间隔中的任何点击事件都会触击图层而不是按钮或链接,从而有效地防止双击双击提交。一旦延迟到期,人们可以*地再次点击任何地方。

选择了500毫秒的延迟,因为它是Windows用来区分连续两次点击的双击的延迟时间。我没有在JavaScript代码中对它进行硬编码,因为我希望能够通过应用程序的属性对其进行更改。

希望这会有所帮助。

+0

用例的好处在于,您无法正确重构遗留代码。但副作用是,你真的阻止任何双击,所以万一用户真的需要执行一次,这是不可能的。另外,为什么不把时间存储在数据集中,而不是存储在innerHTML中(这是暂时可见的)? – ghybs

+0

AFAIK数据集API与HTML5一起出现。我的遗留应用程序仍然坚持HTML4。关于您希望允许双击的情况,我不会在这些页面中使用该技巧,并手动禁用其他按钮,但这可能是我们需要它的页面的0.1%。此外,我认为应该可以重塑图层以部分覆盖窗口,或者以其他方式思考,而不是将其应用于窗口元素,将其应用于页面的一部分。任何我想在答案中尽可能简单并且不提供人们可能不需要的东西 – Aldian

+0

其他可能性,因为该图层的z-索引为1300,所以对于需要双倍大小的控件使用更大的z-索引点击工作。 – Aldian