好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

防止重复点击提交

防止重复点击提交

   首先说说防止重复点击提交是什么意思。

   我们在访问有的网站,输入表单完成以后,单击提交按钮进行提交以后,提交按钮就会变为灰色,用户不能再单击第二次,直到重新加载页面或者跳转。这样,可以一定程度上防止用户重复提交导致应用程序上逻辑错误。

  不妨引深来看,它不一定发生在表单的提交事件上,同样可以发生在ajax的异步请求上。有效地在web客户端采用一定机制去防止重复点击提交,将大大减轻服务器端压力。

  那么,我们就不妨从表单提交及ajax的两种不同请求的处理过程中,来试试如何防止重复点击提交。

   一、表单提交

  就以登录表单为例,代码如下:

 <  form   action  ="login.do"   method  ="post"  > 
     <  input   type  ="text"   name  ="username"   /> 
     <  input   type  ="password"   name  ="password"   /> 
     <  input   type  ="submit"   onclick  ="this.disabled=true; this.value='登录中...'; this.form.submit();"   value  ="登录"   /> 
 </  form  > 

  单击登录按钮进行提交以后,提交按钮就会变为灰色,并且给用户一个友好提示(登录中...),用户不能再单击第二次,直到重新加载页面或者跳转。

  可以发现,我们不需要给这个按钮恢复到可以再次登录的状态,仅仅源于页面重新进行了加载或者跳转。

  但是,针对ajax的请求上,我们又该如何处理呢?

   二、ajax请求

  1  ( function   ($) {
   2      
  3      $('.J-login').click( function   () {
   4      
  5           var  loginBtn =  this  ;
   6          
  7           //  1.先进行表单验证 
  8           //  ...... 
  9          
 10           //  2.让提交按钮失效,以实现防止按钮重复点击 
 11          $(loginBtn).attr('disabled', 'disabled' );
  12          
 13           //  3.给用户提供友好状态提示 
 14          $(loginBtn).text('登录中...' );
  15          
 16           //  4.异步提交 
 17           $.ajax({
  18              url: 'login.do' ,
  19              data: $( this ).closest('form[name="loginForm"]' ).serialize(),
  20              type: 'post' ,
  21              success:  function  (msg){
  22                  
 23                   if  (msg === 'ok' ) {
  24                      alert('登录成功!' );
  25                      
 26                       //  TODO 其他操作... 
 27                  }  else   {
  28                      alert('登录失败,请重新登录!' );
  29                      
 30                       //  5.让登陆按钮重新有效 
 31                      $(loginBtn).removeAttr('disabled' );
  32                   }
  33      
 34               }
  35           });
  36          
 37       });
  38      
 39  })(jQuery);

  可以发现,当登录失败后,需要重新让登录按钮具有登录事件。

  当然,我们可以用一个更加优雅的方式来代替之。

  1  ( function   ($) {
   2      
  3      $('.J-login').click( function   () {
   4      
  5           var  loginBtn =  this  ;
   6          
  7           //  1.先进行表单验证 
  8           //  ...... 
  9          
 10           //  2.异步提交 
 11           $.ajax({
  12              url: 'login.do' ,
  13              data: $( this ).closest('form[name="loginForm"]' ).serialize(),
  14              type: 'post' ,
  15              beforeSend:  function   () {
  16                   //  3.让提交按钮失效,以实现防止按钮重复点击 
 17                  $(loginBtn).attr('disabled', 'disabled' );
  18                  
 19                   //  4.给用户提供友好状态提示 
 20                  $(loginBtn).text('登录中...' );
  21               },
  22              complete:  function   () {
  23                   //  5.让登陆按钮重新有效 
 24                  $(loginBtn).removeAttr('disabled' );
  25               },
  26              success:  function  (msg){
  27                  
 28                   if  (msg === 'ok' ) {
  29                      alert('登录成功!' );
  30                      
 31                       //  TODO 其他操作... 
 32                  }  else   {
  33                      alert('登录失败,请重新登录!' );
  34                   }
  35      
 36               }
  37           });
  38          
 39       });
  40      
 41  })(jQuery);

  在这里,我仅仅举了一个最为简单的例子,还有很多其他的方式进行防止重复点击提交,如

  1> 定义标志位:

    点击触发请求后,标志位为false量;请求(或者包括请求后具体的业务流程处理)后,标志位为true量。通过标志位来判断用户点击是否具备应有的响应。

  2> 卸载及重载绑定事件:

    点击触发请求后,卸载点击事件;请求(或者包括请求后具体的业务流程处理)后,重新载入绑定事件。

  3> 替换按钮DOM

    点击触发请求后,将按钮DOM对象替换掉,自然而然此时不在具备点击事件;请求(或者包括请求后具体的业务流程处理)后,给新的按钮DOM定义点击事件。

  当然,还有其他的方式进行实现,欢迎各位博友补充。

   三、请求频度

  相信大家碰到过这样的业务,我们允许它重复点击(或者其他用户事件),但是不允许在一定的时间内超过次数XX次。这从用户友好体验及服务器承受压力选取了一个折中方案。

  最合适不过的例子,莫过于关键字搜索匹配了。

  相信大家定然首先想到节流函数了。

  1   var  timer =  null  ;
   2  
  3  $(input).keyup( function  (){
   4      
  5       var  value = $( this  ).val();
   6      
  7       clearTimeout(time); 
   8        
  9       //  如果键盘敲击速度太快,小于100毫秒的话就不会向后台发请求,但是最后总会进行一次请求的。 
 10      timer = setTimeout( function  () {
  11           //  触发请求 
 12           $.ajax({
  13              url: 'typeahead.do' ,
  14              type: 'get' ,
  15               data: value,
  16              success:  function   () {
  17                   //  显示匹配结果 
 18                   //  ...... 
 19               }
  20           });
  21      },100 );
  22      
 23  });

   四、总结

  从宏观意义上来讲,我们需要对每一个按钮去做”防止重复点击提交“,面对这种情况,我们便可以采用一定策略来对其进行封装实现(如定义通用按钮类绑定事件)。

  从具体情况上来讲,我们并不需要对每一个按钮都去做”防止重复点击提交“,仅仅需要对某些可能具有复杂后台业务逻辑、或者文件上传、或者调用其他非本工程接口导致网络延迟等等情况需要去做”防止重复点击提交“。与此同时,我们必须要给予用户友好提示(如文本提示、渲染loading条、显示文件上传进度条等等)。两者需要一起来看、一起来做。当然,我们可以单独提取状态显示这个实现逻辑。代码如下——

  1   //  全站ajax加载提示 
  2  ( function   ($) {
   3  
  4       var  str = '<div class="ajax-status" style="display: none;">'
  5              +    '<div class="ajax"><img src="' + publicPath + 'img/loading.gif" width="20" height="20" />数据加载中...</div>'
  6              +'</div>' ;
   7  
  8       var  dom = $(str).prependTo('body' );
   9  
 10      $(document).ajaxStart( function  (){
  11          dom.stop( true , false ).queue( function  (){
  12              $( this  ).show().dequeue();
  13           });
  14       });
  15  
 16      $(document).ajaxStop( function  (){
  17          dom.queue( function  (){
  18              $( this  ).hide().dequeue();
  19           });
  20       });
  21  
 22  })(jQuery);

  总之,”防止重复点击提交“的应用场景及实现方式有很多,需要根据具体项目情况具体来定。

  

 

 

 

分类:  JavaScript

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于防止重复点击提交的详细内容...

  阅读:35次