<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何真正優(yōu)雅解決按鈕”重復(fù)點擊“問題?

          共 2452字,需瀏覽 5分鐘

           ·

          2020-12-06 12:34

          關(guān)注公眾號?前端人,回復(fù)“加群

          添加無廣告優(yōu)質(zhì)學(xué)習(xí)群

          一、對思否的一點吐槽

          思否上的許多按鈕都沒有做重復(fù)點擊檢測的問題,往往導(dǎo)致點擊沒反應(yīng),多次點擊后突然發(fā)表多條相同內(nèi)容,比如和一位同學(xué)的私信:

          又如一個問題下的評論:

          如果你在這篇文章下發(fā)表評論,可以不小心多點幾下"提交評論"按鈕,會發(fā)現(xiàn)也存在相同的問題~~~

          這個問題怎么解決呢?

          簡單點,使用一個lock標(biāo)記,在請求發(fā)出時上鎖,上鎖后就不可以再發(fā)請求,可以在請求結(jié)束后解鎖:

          let?clickButton?=?(function?()?{
          ??let?lock?=?false
          ??return?function?(postParams)?{
          ????if?(lock)?return
          ????lock?=?true
          ????//?假設(shè)使用axios發(fā)送請求
          ????axios.post('urlxxx',?postParams).then(
          ??????//?表單提交成功
          ????).catch(error?=>?{
          ??????//?表單提交出錯
          ??????console.log(error)
          ????}).finally(()?=>?{
          ??????//?不管成功失敗?都解鎖
          ??????lock?=?false
          ????})
          ??}
          })()

          button.addEventListener('click',?clickButton)

          當(dāng)然對于button按鈕,可以使用setAttribute('disabled', xxx)removeAttribute('disabled')來代替lock標(biāo)記。

          這個方案問題在于,對于每一次按鈕點擊,我們都要寫個lock標(biāo)記,相當(dāng)于重復(fù)的邏輯會出現(xiàn)在代碼的各個地方——是不是可以封裝一下呢?

          二、封裝按鈕鎖定、解鎖邏輯

          寫一個裝飾器將邏輯封裝起來:

          function?ignoreMultiClick(func,?manual?=?false)?{
          ??let?lock?=?false
          ??return?function?(...args)?{
          ????if?(lock)?return
          ????lock?=?true
          ????let?done?=?()?=>?(lock?=?false)
          ????if?(manual)?return?func.call(this,?...args,?done)
          ????let?promise?=?func.call(this,?...args)
          ????Promise.resolve(promise).finally(done)
          ????return?promise
          ??}
          }

          將想監(jiān)聽點擊回調(diào)函數(shù)func作為傳遞給ignoreMultiClick進行裝飾,會返回一個新的函數(shù),使用該函數(shù)作為點擊的回調(diào)事件即可。

          有兩種方法解鎖:

          手動解鎖:

          可以給ignoreMultiClick傳遞一個參數(shù)manual,意思是主動調(diào)用解鎖。

          若該參數(shù)為truthy,則點擊事件觸發(fā)時會給原始的點擊回調(diào)func傳遞一個參數(shù)done,done是一個函數(shù),調(diào)用它可以解鎖。

          自動解鎖:

          可以使原監(jiān)聽函數(shù)func返回一個promise,在該promise決議后自動執(zhí)行解鎖操作。

          因為Promise管理回調(diào)函數(shù)非常方便,并且像axios這樣非常常用的請求庫返回值本身也是一個promise,所以默認(rèn)情況使用這種方式。

          當(dāng)然返回promise并不是必須的,有時候我們在發(fā)請求前會進行一些驗證,驗證沒通過則直接return,此時裝飾器函數(shù)也能正常處理,因為使用Promise.resolve包裹了一下promise:Promise.resolve(promise).finally(done)。

          三、使用實例

          自動解鎖使用例子:

          let?clickButton?=?ignoreMultiClick(function?(postParams)?{
          ??//?假設(shè)有一些檢測表單的操作,檢查不通過則直接返回
          ??if?(!checkForm()){
          ???return?done()
          ??}???
          ??//?返回promise
          ??return?axios.post('urlxxx',?postParams).then(
          ????//?表單提交成功
          ??).catch(error?=>?{
          ????//?表單提交出錯
          ????console.log(error)
          ??})
          })
          button.addEventListener('click',?clickButton)

          手動解鎖:

          let?clickButton?=?ignoreMultiClick(function?(postParams,?done)?{
          ??//?表單驗證不通過解鎖
          ??if?(!checkForm()){
          ???return?done()
          ??}??
          ??axios.post('urlxxx',?postParams).then(
          ????//?表單提交成功
          ??).catch(error?=>?{
          ????//?表單提交出錯
          ????console.log(error)
          ??}).finally(()?=>?done())?//?請求結(jié)束解鎖
          })
          button.addEventListener('click',?clickButton)

          普通場景下還是自動解鎖比較簡單,因為可能有多個條件分支,手動解鎖需要在每一個返回的地方都調(diào)用done。

          原文:segmentfault.com/a/1190000038291773

          1.你的點贊、在看 是對【鬼哥】最大的支持,一鍵三連吧

          2.關(guān)注公眾號前端人,回復(fù)資料包領(lǐng)取我整理的前端進階資料包

          3.回復(fù)加群,加入前端進階群,和小伙伴一起學(xué)習(xí)討論!

          瀏覽 36
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  13一16女处被毛片视频 | 操逼国产无码 | 视频官网毛片 | 操逼网站免费看 | 影音先锋色av |