微信小程序新坑 swiper监听被使用setData后会不停触发swiper的滑动事件

swiper对象在真机产生滑动事件一次滑动就无限地被触发的原因分析

swiper切换的滑动原理

swiper对象本身是通过h5触摸事件触发的swiper对象内部所封装的滑动事件处理函数,通过这个切换处理函数实现的swiper对象的子对象swiper-item所生成的模块的滑动切换效果

swiper切换的真机滑动产生异常的罪魁祸首

原生swiper对象会对内部的滑动动画函数的调用进行执行之前的条件限制

简而言之就是指swiper对象对swiper对象的H5触摸事件:touchstart、touchmove、touchend做了状态记录,

每次执行之前都会通过状态属性判断,只有touchstart、touchmove事件对应的状态属性已触发并且touchend对应的状态属性未触发时才执行swiper对象的滑动动画函数

可是,小程序的官方并没有对touchend进行状态记录,所以导致swiper对象没有及时记录用户的手指离开状态,从而造成只要这个swiper对象的参数值被重新传参时就会触发swiper对象的动画切换事件

官方bug说明:

官方说这个bug是由setData造成的,setData的底层就是对属性所对应的子对象或虚拟DOM进行重新渲染,因为swiper对象被重新渲染的缘故,所以swiper对象的切换事件会被触发两次,第一次由用户触摸滑动时触发,第二次为swiper对象被重新渲染时触发swiper对象的切换事件

由于swiper对象的监听函数恰好在监听这个事件,监听函数每次又恰好是执行setData,所以就导致如果不对setData这段代码做条件限制,setData就会不停执行,不停触发事件,从而造成swiper对象的切换在真机犹如中毒似的不停触发

为什么在swiper对象之外的DOM元素的触摸事件只能用bind不能用catch?

catch的原理为阻止事件的捕获和事件的冒泡,在JS中事件为先捕获后冒泡,同时触发顺序也是父DOM和子DOM的事件同时触发时,会触发父而不触发子

此时,由于swiper对象中的视图容器已经设置touchstar,但swiper对象的视图容器又是swiper对象的外层容器的子容器,所以这个事件如果用catch就会导致只触发父级的事件,不触发子级的事件,从而出现真机上swiper对象无法滑动的现象bug

因为swiper对象要触发滑动函数的调用需要触发swiper的视图容器的touchstar和touchmove事件,所以必须确保swiper对象的touchstar和touchmove事件的实时触发,才能确保swiper对象的滑动函数的实时执行

解决方法

在swiper对象的外层设置触摸监听,并限定监听函数的无限次执行监听事件对应的监听逻辑函数 ,使setData不会无限次执行

猜你喜欢

转载自blog.csdn.net/qq_38603437/article/details/92009924