整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          a標簽和button按鈕只允許點擊一次,防止重復提交

          a標簽和button按鈕只允許點擊一次,防止重復提交

          utton

          方法:加上屬性disabled=“disabled” 或者 disabled=“true”

          <button id="btn" disabled="disabled">確定</button>
          2>Javascript里
          <script>
           $("#btn").attr("disabled","true");
           $("#btn").attr("disabled","disabled");
           $("#btn").attr("disabled","false");
           $("#btn").removeAttr("disabled","disabled");
          </script>
          

          a標簽

          方法:在點擊一次后,解除綁定。

          <a id="mybtn">button</a>
          <script>
           $("a").click(function(){
           alert("1");
           $(this).css("color","#CCC");
           $(this).unbind("click");
           })
          </script>
          

          或者:

          常開發中經常會用到表單提交,如果表單沒有做防重復提交,可能會引起系統業務邏輯異常,導致系統數據錯亂

          下面我給出一套常用的解決方案,前端用javascript鎖防止重復點擊,后端驗證session里面的token值防止重復提交

          一、引起表單重復提交有以下幾種常見場景

          • 重復點擊提交按鈕。包括惡意的連續點擊提交按鈕,或因為網絡慢、服務器處理速度慢等引起的用戶多次點擊
          • 表單提交處理完后,通過瀏覽器的后退按鈕回到原頁面再次點擊提交按鈕
          • 通過點擊瀏覽器的刷新按鈕,導致表單重復提交
          • 通過瀏覽器的歷史記錄,獲取表單提交的URL地址,再次訪問

          二、前端

          session中設置一個token

          String token=UUID.randomUUID().toString();
          session.setAttribute("formToken", token);

          表單html

          <html>
          <head>
          <title>員工信息</title>
          </head>
          <body>
            <form method="post" action="/postForm">
              姓名:<input type="text" name="userName">
              年齡:<input type="text" name="age">
              性別:<input type="text" name="sex">
              <input type="hidden" name="formToken" value="${formToken}">
              <input type="button" value="保存" onclick="infoSave()">
            </form>
          </body>
          </html>

          js防止重復點擊

          <script>
          var isSaving=false;
          function infoSave() {
              if(isSaving) {
             		 return false;
              }
              isSaving=true;
              Ajax.post('https://xxx.xxx.xxx/infoSave',params).then(function(res){
                isSaving=false;
                if(res.code==200){
                	alert("修改成功");
                }else{
                	alert(res.message);
                }
                window.location.reload();
              });
          }
          </script>

          三、服務端

          String Token1=request.getParameter("formToken");
          String Token2=(String) session.getAttribute("formToken");
          if (Token1 !=null && Token1.equals(Token2)) {
            // 處理表單提交 ...
            // 刪除標識符
            session.removeAttribute("formToken");
          }else{
          	// 重復提交,給出錯誤提示
          } 

          四、總結

          一般情況下采用JS腳本方式和服務端方式兩種結合已可防止表單重復提交,針對特殊業務要求的可采用數據庫唯一性約束限制等方式來強制保證業務邏輯上的數據唯一要求。

          所周知,函數節流(throttle)是 JS 中一個非常常見的優化手段,可以有效的避免函數過于頻繁的執行。

          舉個例子:一個保存按鈕,為了避免重復提交或者服務器考慮,往往需要對點擊行為做一定的限制,比如只允許每300ms提交一次,這時候我想大部分同學都會到網上直接拷貝一段throttle函數,或者直接引用lodash工具庫

          btn.addEventListener('click', _.throttle(save, 300))

          其實除了 JS 方式, CSS 也可以非常輕易的實現這樣一個功能,無需任何框架庫,一起看看吧

          一、CSS 實現思路分析

          CSS 實現和 JS 的思維不同,需要從另一個角度去看待這個問題。

          比如這里的需要對點擊事件進行限制,也就是禁用點擊事件,想想有什么方式可以禁用事件,沒錯,就是pointer-events;

          然后是時間的限制,每次點擊后需要自動禁用300ms,時間過后重新恢復,那么,有什么特性和時間以及狀態恢復有關呢?沒錯,就是animation;

          除此之外,還需要有觸發時機,這里是點擊行為,所以必然和偽類:active有關聯。

          因此,綜合分析,實現這樣一個功能需要用到pointer-events、animation以及:active,那么如何將這些思路串聯起來呢?

          思考3秒...

          你想到了嗎?

          其實這種場景可以理解成是對 CSS 動畫的控制,比如有一個動畫控制按鈕從禁用->可點擊的變化,每次點擊時讓這個動畫重新執行一遍,在執行的過程中,一直處于禁用狀態,是不是就達到了“節流”的效果了?

          接下來看看具體實現

          二、CSS 動畫的精準控制

          假設有一個按鈕,綁定了一個點擊事件

          <button onclick="console.log('保存')">保存</button>

          這時的按鈕連續點擊就會不斷地觸發,效果如下

          下面定義一個關于pointer-events的動畫,就叫做 throttle

          @keyframes throttle {
            from {
              pointer-events: none;
            }
            to {
              pointer-events: all;
            }
          }

          很簡單吧,就是從禁用可點擊的變化。

          接下來,將這個動畫綁定在按鈕上,這里為了方便測試,將動畫設置成了2s

          button{
            animation: throttle 2s step-end forwards;
          }

          注意,這里動畫的緩動函數設置成了階梯曲線,step-end,它可以很方便的控制pointer-events的變化時間點。

          如下示意,pointer-events在0~2秒內的值都是none,一旦到達2秒,就立刻變成了all,由于是forwards,會一直保持all的狀態

          最后,在點擊時重新執行一遍動畫,只需要在按下時設置動畫為none就行了

          這個技巧之前在這篇文章中有更詳細的介紹: CSS 實現按鈕點擊動效的套路

          實現如下

          button:active{
            animation: none;
          }

          為了演示方便,我們暫時把顏色變化也加在動畫里

          @keyframes throttle {
            from {
              color: red;
              pointer-events: none;
            }
            to {
              color: green;
              pointer-events: all;
            }
          }

          現在如果文字是red,表示是禁用態,只有是green,才表示可以被點擊,非常清晰明了,如下

          下面是最終點擊對比效果,很好地限制了點擊頻率

          完整代碼如下,就這么幾行,如果需要改限制時間,直接改動畫時間就行了

          button{
            animation: throttle 2s step-end forwards;
          }
          button:active{
            animation: none;
          }
          @keyframes throttle {
            from {
              pointer-events: none;
            }
            to {
              pointer-events: all;
            }
          }

          三、CSS 實現的其他思路

          借用這種思路,也可以很輕松的實現節流的效果。而且為了更好的體驗,可以用上真正的按鈕禁用

          btn.disabled=true

          具體思路是這樣的,通過:active去觸發transition變化,然后通過監聽transition回調去動態設置按鈕的禁用狀態,實現如下

          定義一個無關緊要的過渡屬性,比如opacity

          button{
            opacity: .99;
            transition: opacity 2s;
          }
          button:not(:disabled):active{
            opacity: 1;
            transition: 0s;
          }

          然后監聽transition的起始回調

          // 過渡開始
          document.addEventListener('transitionstart', function(ev){
            ev.target.disabled=true
          })
          // 過渡結束
          document.addEventListener('transitionend', function(ev){
            ev.target.disabled=false
          })

          這樣做的最大好處是,這部分禁用的邏輯是完全和業務邏輯是解耦的,可以在任意時候,任意場合下無縫接入,也不受框架和環境影響,效果如下

          四、總結一下

          以上通過 CSS 的思路實現了類似“節流”的功能,相比 JS 實現而言,實現更精簡、使用更簡單,沒有框架限制,下面一起總結一下實現要點:

          1. 函數節流是一個非常常見的優化方式,可以有效避免函數過于頻繁的執行
          2. CSS 的實現思路和 JS 不同,重點在于在于找到和該場景相關聯的屬性
          3. CSS 實現“節流”其實就是控制一個動畫的精準控制,假設有一個動畫控制按鈕從禁用->可點擊的變化,每次點擊時讓這個動畫重新執行一遍,在執行的過程中,一直處于禁用狀態,這樣就達到了“節流”的效果
          4. 還可以通過 transition 的回調函數動態設置按鈕禁用態
          5. 這種實現的好處在于禁用邏輯和業務邏輯是完全解耦的



          原文鏈接:https://juejin.cn/post/7165828047520661534


          主站蜘蛛池模板: 亚洲Av无码一区二区二三区| 一区二区三区免费精品视频| 国产乱码精品一区二区三区麻豆| 精品少妇一区二区三区在线| 国产一区二区三区在线免费| 日韩视频在线一区| 久久中文字幕无码一区二区| 国产99视频精品一区| 午夜一区二区免费视频| 国产伦一区二区三区高清| 国产婷婷色一区二区三区| 一区二区三区视频在线观看| 亚洲综合国产一区二区三区| 日韩免费一区二区三区| 性色AV 一区二区三区| 国产综合一区二区| 日韩一区二区三区射精| 国产精品一区二区资源| 欧洲精品无码一区二区三区在线播放| 亚洲爆乳精品无码一区二区三区| 亚洲日韩AV一区二区三区中文| 日韩精品人妻av一区二区三区| 久久精品一区二区国产| 免费高清av一区二区三区| 久久亚洲中文字幕精品一区| 亚洲一区二区三区在线| 一区精品麻豆入口| 中字幕一区二区三区乱码| 一区二区三区免费精品视频| 在线观看国产一区二三区| 亚洲国产成人久久综合一区77| 精品人无码一区二区三区| www.亚洲一区| 国内精品视频一区二区三区| 伊人色综合一区二区三区| 国产伦精品一区二区三区免.费| 精品无码国产一区二区三区AV| 日韩AV在线不卡一区二区三区| 亚洲欧洲专线一区| 无码人妻少妇色欲AV一区二区| 秋霞电影网一区二区三区|