微信小程序——swiper抖动问题解决以及节流、防抖

足彩365 2025-08-01 04:33:18 阅读: 4780

目录

一、引出

二、防抖函数

1.为什么需要防止抖动的原因

2.函数防止抖动的原理

3.防抖动代码函数实现

4.在小程序当中使用的防抖函数

三、节流函数

1.为什么需要节流的原因

2.函数节流的原理

3.节流函数代码的实现

四、区别与使用的场景

1.什么时候会用到节流函数和防抖函数?

2.防抖函数和节流函数的区别

五、总结

一、引出

在写banner组件的时候遇到的一个问题,在写好banner的轮播图组件之后,在使用的时候总是会偶尔出现一个抖动的效果(以下是一个出现抽搐的效果图)

1680162792547.mp4https://five-min.yuque.com/attachments/yuque/0/2023/mp4/32698987/1680188074840-3ad552e2-4a85-408e-8879-8f74ad6bf9db.mp4

这样让我个人感觉就体验不好,更何况是用户,然后上网查找了一下原因,在微信开发者文档中发现了问题的所在

在此处可以看到在1.4.0开始之后的change事件中添加了一个source的字段,可以来展示是什么原因导致的change事件触发,在使用swiper的时候不排除会出现刚刚上面的视频中的问题,这就是这里的其他原因触发了change事件,从而导致的抖动,这里我的解决方法如下:

swiperChange: function (e: { detail: { current: any; source: any; }; }) {

let current = e.detail.current

let source = e.detail.source

if (source == 'autoplay' || source == 'touch') {

//根据官方 source 来进行判断swiper的change事件是通过什么来触发的,autoplay是自动轮播。touch是用户手动滑动。其他的就是未知问题。抖动问题主要由于未知问题引起的,所以做了限制,只有在自动轮播和用户主动触发才去改变current值,达到规避了抖动bug

this.setData({

index: current

})

}

},

然后就对这一部分进行了一个深入的了解,在网上查找了一下有关防抖动的方法以及产生的原因和进行节流的方法

二、防抖函数

1.为什么需要防止抖动的原因

前端开发过程中,有一些事件,常见的例如,onresize,scroll,mousemove ,mousehover 等,会被频繁触发(短时间内多次触发),不做限制的话,有可能一秒之内执行几十次、几百次,如果在这些函数内部执行了其他函数,尤其是执行了操作 DOM 的函数(浏览器操作 DOM 是很耗费性能的),那不仅会浪费计算机资源,还会降低程序运行速度,甚至造成浏览器卡死、崩溃。

2.函数防止抖动的原理

函数防抖,就是指触发事件后,在 n 秒内函数只能执行一次,如果触发事件后在 n 秒内又触发了事件,则会重新计算函数延执行时间,函数防抖的要点,是需要一个 setTimeout 来辅助实现,延迟运行需要执行的代码。如果方法多次触发,则把上次记录的延迟执行代码用 clearTimeout 清掉,重新开始计时。若计时期间事件没有被重新触发,等延迟时间计时完毕,则执行目标代码。

3.防抖动代码函数实现

function debounce(fn,wait){

var timer = null;

return function(){

if(timer !== null){

clearTimeout(timer);

}

timer = setTimeout(fn,wait);

}

}

function handle(){

console.log(Math.random());

}

window.addEventListener("resize",debounce(handle,1000));

可以用此代码做一个例子:在窗口的尺寸发生变化的时候会触发resize,然后调用debounce这个函数,然后就设置了一个倒计时,当重复多次的触发这个函数时,当时间没到设定时间的时候就会清除倒计时,然后重新设置,避免了多次调用我们想调用的handle函数(这里仅做展示使用,实际上handle函数没有实际的用处,只是为了方便观察),从而达到了一个防抖的效果。

4.在小程序当中使用的防抖函数

内部使用,不需要使用外部模块。

onLoad: function (options) {

console.log(options);

this.debounce = this.debounce();// 防抖函数,在此处初始化

// 若不初始化,函数主体不执行

}

// debounce函数,就是事件触发的函数,名字可以随意取名

debounce : function () {

var timeOut = null;

return () => {

clearTimeout(timeOut);

timeOut = setTimeout(() => {

// 事件函数中要执行的代码块

// 改写原函数异常方便、简洁

}, 300);

}

}

此处的理解与上处的理解类似,也是用倒计时的方法防止抖动

三、节流函数

1.为什么需要节流的原因

在一个登录页面,如果用户不停的点击登录界面,如果没有做节流处理,那么就会多次向接口发出请求,会重复多次的请求,有的地方还会造成鬼畜动画,所以这个时候就需要节流来做限制,节流函数里面也需要使用定时器setTimeout,但是这里与防抖的区别是,节流是一段时间内不管你触发多少次,只响应一次。

2.函数节流的原理

定义一个变量,然后通过这个变量的值来决定是不是执行此函数,例如定义begin=true,将要执行的部分放入if语句中,用begin当做是否进入语句的条件,当第一次点击登录以后将begin变成flase,那么后面再次进行点击的时候就不会进入if语句,在语句中使用一个倒计时,到达规定时间在将begin的值变回ture就可以了,这样就可以达到一个节流的效果。(这里的begin也被称为节流阀)

3.节流函数代码的实现

function throttle(fn, interval) {

var enterTime = 0;//触发的时间

var gapTime = interval || 300 ;//间隔时间,如果interval不传,则默认300ms

return function() {

var context = this;

var backTime = new Date();//第一次函数return即触发的时间

if (backTime - enterTime > gapTime) {

fn.call(context,arguments);

enterTime = backTime;//赋值给第一次触发的时间,这样就保存了第二次触发的时间

}

};

}

此处的代码便于封装在公共的js代码中做公共方法调用

四、区别与使用的场景

1.什么时候会用到节流函数和防抖函数?

调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时需要一次到位(防抖)文本编辑器实时保存,当无任何更改操作一秒后进行保存(防抖)按钮重复多次点击(节流)百度搜索框,搜索联想功能(节流)

2.防抖函数和节流函数的区别

防抖函数是在单位时间(>1)随便触发多少次事件,只要这次触发的时间与上次触发的时间只差不到1s,都不执行;节流函数是在单位时间(>1)随便触发多少次事件,只要过了1s,就会执行一次。

两个函数都能达到防止重复触发的功能。但是函数防抖是 n秒后延迟执行;而函数节流是立马执行,n秒后再立马执行。

具体的使用主要看需求:

当我们只需要处理最后一次触发事件时,用函数防抖当事件触发过于频繁,我们需要限制事件处理程序的调用频率时,用函数节流

五、总结

这次小编也是在做小程序开发的途中发现的问题就想着记录一下咯,那今天的分享就到这里结束 ,咱们下期再见呀!