目录

微信小程序防止重复点击的两种处理方法

目录

微信小程序防止重复点击的两种处理方法

当用户点击按钮或控件时,如果响应比较慢,往往会重复点击,另外也会存在用户故意反复快速点击的情况,这种时候就会多次触发点击事件造成非期望的结果。如何解决或避免这个问题呢?一般来说有两种情况。 1、点击事件是执行请求 这种情况下可以在请求执行之前显示一个模式的加载框,请求完成后再关闭加载框,由于小程序在1.1.0版本基础库才支持wx.showLoading,因此需要对低版本做兼容处理,代码如下:



1. function showLoading(message) {  
        
        if (wx.showLoading) {    
        
        // 基础库 1.1.0 微信6.5.6版本开始支持,低版本需做兼容处理
2. wx.showLoading({      
        
        title: message,      
        
        mask: 
        
        true
3. });
4. } 
        
        else {    
        
        // 低版本采用Toast兼容处理并将时间设为20秒以免自动消失
5. wx.showToast({      
        
        title: message,      
        
        icon: 
        
        'loading',      
        
        mask: 
        
        true,      
        
        duration: 
        
        20000
6. });
7. }
8. }

10. function hideLoading() {  
         
         if (wx.hideLoading) {    
         
         // 基础库 1.1.0 微信6.5.6版本开始支持,低版本需做兼容处理
11. wx.hideLoading();
12. } 
         
         else {    wx.hideToast();
13. }
14. }

我们可以将显示加载框和关闭加载框的代码放在公共的代码里面比如util,然后在使用时直接调用即可。



1. function request() {
2. util.showLoading(
        
        '加载中...');
3. wx.request({
4. url: app.globalData.host + 
        
        'xxx',
5. data: {...},
6. method: 
        
        'GET',
7. success: 
        
        function (res) {
8. util.hideLoading()
9. ...
10. },
11. fail: 
         
         function (res) {
12. util.hideLoading()
13. ...
14. }
15. })
16. }

2、点击事件是页面跳转 当点击事件是页面跳转时,不太适合显示加载框,但小程序的页面跳转并不是很快,如果不作处理又会导致用户反复点击打开多个页面,这里可以使用限制按钮或控件的点击间隔的方式处理,同样可以将这个方法放到公共的代码里面比如util,然后在使用时直接调用即可。



1. function buttonClicked(self) {  self.setData({
2. buttonClicked: 
        
        true
3. })
4. setTimeout(
        
        function () {    self.setData({
5. buttonClicked: 
        
        false
6. })
7. }, 
        
        500)
8. }

首先需要在页面对应的js文件里面增加一个buttonClicked数据对象,然后在点击事件里面调用上述方法。



1. Page({
2. data: {
3. buttonClicked: 
        
        false
4. },
5. click: 
        
        function (e) {
6. util.buttonClicked(
        
        this);    
        
        var id = e.currentTarget.dataset.id;
7. wx.navigateTo({
8. url: 
        
        '../detail/detail?id=' + id
9. })
10. },
11. })

另外,在wxml的点击控件中通过buttonClicked判断是否可以点击,可以用bindtap也可以用disabled



1. <view bindtap=
        
        "{{!buttonClicked?'click':''}}" data-id=
        
        "{{id}}" />
2. <button bindtap="{{!buttonClicked?'click':''}}" data-id="{{id}}" />
3. <button bindtap="click" disabled="buttonClicked" data-id="{{id}}" />

未完待续,后面找到其他更好的方法会再更新,也欢迎━(`∀´)ノ亻!大家在文下评论交流,谢谢!

有时候点击太快的话以上方法在真机赏并不起作用,还是会发起两次请求或者打开多个相同的页面,

下面提供更科学的办法:

  1. data里面定义3个属性


1. touchStartTime: 
        
        0, 
        
        // 触摸开始时间
2. touchEndTime: 
        
        0, 
        
        // 触摸结束时间
3. lastTapTime: 
        
        0 
        
        // 最后一次单击事件点击发生时间
2.页面触发这3个事件


1. <view @tap=
        
        "doubleTap" @touchstart=
        
        "touchStart" @touchend=
        
        "touchEnd">测试重复点击事件<
        
        /view>
3.methods里面添加3个方法


1. // 防止重复点击
2. touchStart(e) {
3. this.touchStartTime = e.timeStamp;
4. },
5. touchEnd(e) {
6. this.touchEndTime = e.timeStamp;
7. },
8. doubleTap(item, e) {
9. var vm = 
        
        this;
10. // 控制点击事件在350ms内触发,加这层判断是为了防止长按时会触发点击事件
11. if (vm.touchEndTime - vm.touchStartTime < 
         
         350) {
12. // 当前点击的时间
13. var currentTime = e.timeStamp;
14. var lastTapTime = vm.lastTapTime;
15. // 更新最后一次点击时间
16. vm.lastTapTime = currentTime;
17. // 如果两次点击时间在300毫秒内,则认为是双击事件
18. if (currentTime - lastTapTime > 
         
         300) {
19. // do something 点击事件具体执行那个业务
20. }
21. }
22. }