對於一些涉及後端接口請求的單擊事件,不論後端是否作了請求限制,前端仍是有必要進行點擊防重處理的。前端
這樣既能減小對服務器端的壓力,也能有效防止因重複請求而形成一些不可預期的異常。小程序
尤爲是接口請求結果處理的邏輯中有須要調用小程序api,如獲取手機號碼受權、支付、領取卡券這些API。後端
雖然這些API都能調起本身的原生界面,可是從請求到相關原生界面展現出來以前是會有必定的時間的,若是在這個空檔用戶快速點擊,那麼就會形成接口被重複請求,直接回影響到小程序API的調用。api
對於點擊防重,之前用過一種比較笨的方法,就是自定義loading組件,在接口請求開始前loading,API調用complete回調中隱藏loading。數組
自定義loading組件點擊防重:服務器
之因此自定義loading,是因爲小程序的showToast和showLoading只能顯示一個,爲了不showToast的影響,咱們須要自定義一個loading組件;微信
loading組件須要有蒙板,這樣loading的時候能隔離頁面,有效的屏蔽點擊(蒙板能夠設置一個蒙板是否透明的參數,正常調用顯示半透明灰底蒙板,涉及到小程序API不須要灰底蒙板的就顯示透明蒙板)。函數
固然,這種作法只不過是避免showToast影響showLoading的同時,還能夠作點擊防重,若是僅僅是點擊防重,這代碼量就比較多了。測試
若是原生的loading就能知足需求,那麼能夠採用下面的方法進行點擊防重:微信支付
定義點擊標誌變量進行點擊防重:
Page({ data: { ...... isclick: false, //點擊防重標誌 }, /** * 須要作防點擊防重的單擊事件 */ onclick: function() { var self = this if(!self.data.isclick){ self.setData({ isclick:true }) setTimeout(function () { self.setData({ isclick: false }) }, 500); }else{ return; } ...... } ...... })
這種方法,就簡單多了。這裏採用了定時器放開點擊狀態,非特殊狀況,500ms後放開點擊狀態也足夠用了,也不會對用戶體驗形成影響。
固然,若是你不想這麼作,能夠在指定接口調用成功以後或某些操做完成後再放開點擊狀態,但有風險的地方就在於若是這個過程當中一個地方出問題,那麼極可能這個單擊事件已經被鎖定而沒法放開了,用戶重試的機會都沒有,因此這種方法慎用。
對於上邊的代碼,若是須要用到的地方比較多,能夠封裝到公共方法文件中:
//util.js //點擊防重 let isClick=false; let preventDuplicateClicks=function(){ if (!isClick) { isClick=true setTimeout(function () { isClick = false }, 500); return false; } else { return true; } } module.exports = { preventDuplicateClicks: preventDuplicateClicks }
方法調用:
import utils from '../../utils/util.js' Page({ ...... /** * 1.須要防重的單擊事件 */ orderPay: function() { var self = this if(utils.preventDuplicateClicks()) return; ...... }, ...... })
上邊代碼並無處理多個單擊事件的衝突問題,畢竟是同一個標誌變量。可是通常狀況下,用戶連續點擊兩個按鈕的時間已經超過500ms了(有意測試除外)。若是必定要解決,那麼能夠用數組來區分不一樣的單擊事件,示例代碼以下:
/** * 點擊防重函數 * 須要避免衝突的單擊事件須要傳不一樣的index參數,若是不傳視爲不處理衝突,共用一個標誌值 */ let isClick =''; let preventDuplicateClicks = function(index) { if (!index) index=0; if (!isClick[index]) { isClick[index] = true setTimeout(function() { isClick[index] = false }, 500); return false; } else { return true; } } module.exports = { preventDuplicateClicks: preventDuplicateClicks }
調用方法:
//不處理衝突 if (utils.preventDuplicateClicks()) return; //處理衝突 if (utils.preventDuplicateClicks(1)) return;
這樣的話,只要不一樣的單擊事件傳的參數不一樣,那麼不一樣單擊事件的點擊防重就不會衝突。
注意:
1.點擊防重對單擊事件鎖定的時間通常半分鐘足夠了,若是涉及到小程序API調用,如支付、領取卡券類的API,調起API相應頁面的時間通常都會有點久(大於500ms),能夠把這個值設置成1000ms,對用戶體驗不會有影響的,畢竟微信支付、領取卡券之類的界面加載出來沒那麼快,用戶基本上感受不到咱們點擊防重的。
2.若是有須要,給 preventDuplicateClicks 方法再增長一個鎖定時間的參數,這樣使用起來更靈活,能夠知足不一樣需求。