收藏
回答

怎么屏蔽小程序重复点击事件?(有偿)

目前的解决办法是在js里限制提交,首先有一个点击事件的开关,当这个开关为N的时候可进行提交,为Y的时候不能提交,其次就是加了一个时间判断,两次提交时间不能小于3秒,否则也认为是重复提交,但是这样都在后台看到有重复提交数据上传,有大佬知道是什么原因吗?代码如下

代码片段:https://developers.weixin.qq.com/s/grIUofma7qJ3

有大佬能完美解决奉上红包一个

最后一次编辑于  2023-06-26
回答关注问题邀请回答
收藏

6 个回答

  • Ding
    Ding
    2023-06-26

    前端做个防抖,后端可以做个接口幂等

    2023-06-26
    有用
    回复
  • 正青春
    正青春
    2023-06-26

    如果是提交数据到后台,后台判断这个用户有没有提交过(该表里边有没有这个用户的数据),如果有提交,不让提交;如果是需要多次提交的,后台同样判断时间差,多久允许提交一次;

    2023-06-26
    有用
    回复
  • DRA
    DRA
    2023-06-26

    一般来讲,你这个逻辑是没有问题的,但为什么做了限制,仍然会提交两次呢?两种可能

    1.该方法是异步调用的,异步调用就意味着存在多条线程同时运行,当还是y的时候,就有两个或以上线程运行到方法里了,这种情况你给方法设为同步调用就行了;

    2.虽然你设置了时间3s,但你要考虑到,这小段代码运行是毫秒级别的,你设置一个Y参数,还用断位或.你后面的3s就没有起作用,这种情况,你删除那个Y参数,只保留一个3s的条件就可以了

    3.补充一点,这种判断,你直接过滤掉就好了,从用户角度来讲,我点一次,你也正常提交了,但是你还给我一个错误点击的提示,会让我误以为我的操作没有生效

    2023-06-26
    有用
    回复 4
    • 大橘为重
      大橘为重
      2023-06-26
      大佬,能加微信请教一下吗,还是有点没太明白
      2023-06-26
      回复
    • 大橘为重
      大橘为重
      2023-06-26
      js本身是单线程运行啊
      2023-06-26
      回复
    • 大橘为重
      大橘为重
      2023-06-26
      我分析了我的代码,上面您说的几点应该是不存在的,1.目前代码调用是同步的,2.Y参数代表是已为提交状态,已为提交状态或者操作时间小于3秒都禁止提交,这里用“或”感觉没啥问题。
      有一个bug是我做另一个项目发现的,在使用小程序<movable-area>组件时,内部如果存在输入框,在输入完成时触发输入完成事件,调用方法会直接调用两次,用上面那种方法完全防不住,但是这种情况只在Android机型上出现。所以我现在怀疑在按钮那里是不是点击就直接同时触发了两次方法调用。目前后台看到的数据大概有千分之一的概率是重复提交
      2023-06-26
      回复
    • DRA
      DRA
      09-04回复大橘为重
      像这种输入完成就触发的,要么不要用它自带的回调方法,要么屏蔽掉那两次就行了;异步有时候你看代码是看不出来的,但重复调用,你还做了时间限制,那肯定是有异步重复触发,你需要打印日志,从根源一步一步的查,肯定能找到.
      09-04
      回复
  • 大熊
    大熊
    2023-06-26

    参考下我的封装

    https://www.cnblogs.com/520BigBear/p/16328212.html

    2023-06-26
    有用
    回复 1
    • 大橘为重
      大橘为重
      2023-06-26
      感谢大佬,您的逻辑和我的js处理办法应该是一个逻辑
      2023-06-26
      回复
  • 隔壁小张
    隔壁小张
    2023-06-26
    /**
     * 是否重复点击
     */
    class RepeatClick {
      constructor() {
        this.clickTime = 0;
      }
    
    
      isRepeat() {
        return 1 === this.clickTime;
      }
    
    
      begin() {
        this.clickTime = 1;
      }
    
    
      end() {
        this.clickTime = 0;
      }
    }
    
    
    module.exports = {
      RepeatClick
    }
    
    ////////////////////////////////
    
    
    import
     { RepeatClick } from './RepeatClick';
    
    
    /**
     * 间隔多久可再次执行
     */
    class IntervalLoad {
      constructor() {
        this.repeat = new RepeatClick();
      }
    
    
      /**
       * 完成标记
       * @param {number} interval   间隔时间
       * @param {string} toast      提示信息,'none' 不提示
       * @param {boolean} toastMask 是否显示提示蒙层
       * @return true可以再次执行,false不可再次执行
       */
      done(p = { interval1500toast'请勿频繁操作'toastMasktrue }) {
        if (this.repeat.isRepeat()) {
          if ('none' != p.toast) {
            wx.showToast({
              title: p.toast,
              icon'none',
              mask: p.toastMask
            });
          }
          return false;
        }
        this.repeat.begin();
        const that = this;
        // interval秒后可以重新加载
        setTimeout(function () {
          that.repeat.end();
        }, p.interval);
        return true;
      }
    }
    
    
    module.exports = {
      IntervalLoad
    }
    /////////////使用
    
    import {
      IntervalLoad
    } from 'IntervalLoad';
    
    const $interval = new IntervalLoad();
    
    submit() {
       if (!$interval.done()) {
          return;
        }
    }
    
    2023-06-26
    有用
    回复 1
    • 大橘为重
      大橘为重
      2023-06-26
      这段代码没怎么看懂啊
      2023-06-26
      回复
  • 胡胡胡小朋友
    胡胡胡小朋友
    2023-06-26

    button有个disabled属性,设置它比showLoading靠谱

    2023-06-26
    有用
    回复 3
    • 大橘为重
      大橘为重
      2023-06-26
      disabled 属性是在视图层,设置属性再渲染到视图层会有几毫秒左右的延时,我在js里直接判断不比disabled 属性拦截的更快么,我这样理解不知道对不对,请大佬指教
      2023-06-26
      回复
    • 胡胡胡小朋友
      胡胡胡小朋友
      2023-06-26回复大橘为重
      理论上差不了多少,解决重复提交问题我这边一贯的解决方法就是先让用户点不了,这个成本最低
      2023-06-26
      回复
    • 大橘为重
      大橘为重
      2023-06-26回复胡胡胡小朋友
      行吧,我也先加上这个属性试试吧
      2023-06-26
      回复
登录 后发表内容