1. 程式人生 > >微信小程序開發——點擊防重的解決方案

微信小程序開發——點擊防重的解決方案

dex 沒有 特殊情況 sel 半透明 dup ports 手機 超過

對於一些涉及後端接口請求的單擊事件,不論後端是否做了請求限制,前端還是有必要進行點擊防重處理的。

這樣既能減少對服務器端的壓力,也能有效防止因重復請求而造成一些不可預期的異常。

尤其是接口請求結果處理的邏輯中有需要調用小程序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了(有意測試除外)。如果一定要解決,那麽可以用數組來區分不同的單擊事件,示例代碼如下:

let isClick = new Array();
let preventDuplicateClicks = function(index) {
  if (!index) return;
  if (!isClick[index]) {
    isClick[index] = true
    setTimeout(function() {
      isClick[index] = false
    }, 500);
    return false;
  } else {
    return true;
  }
}
module.exports = {
  preventDuplicateClicks: preventDuplicateClicks
}

調用方法:

if (utils.preventDuplicateClicks(1)) return;

這樣的話,只要不同的單擊事件傳的參數不同,那麽不同單擊事件的點擊防重就不會沖突。

微信小程序開發——點擊防重的解決方案