swiper匀速运动mySwiper.autoplay.stop()延迟执行问题

352 阅读2分钟

问题表现

使用的是swiper/react组件想要实现的效果是匀速轮播,hover立刻停止,hover离开之后立马运动;但是如果只是使用swiperRef.current.swiper.autoplay.stop();并没有立刻停止,这是因为swiperautopaly.stop()方法只是暂停下一次的切换,而本次的切换还是要进行完,因此会有一个看起来延迟的效果;

82892907728ccf7287df55115d2549f5.gif 代码如下:

 const swiperConfig = {
        initialSlide: -2,
        direction: 'horizontal',
        slidesPerView: 12,
        loop: true,
        speed: 6000,
        dir: 'ltr', // 默认从右往左运行,‘rtl’ 从左往右运动
        centeredSlides: true,
        spaceBetween,
        autoplay: {
            delay: 0,
            disableOnInteraction: false, // 用户操作后是否停止自动播放,默认为true,设为false则不会停止
            pauseOnMouseEnter: true // 开启此功能,鼠标置于swiper时暂停自动切换,鼠标离开时恢复自动切换。
        }
    };
    
     const handleMouseenter = () => {
        if (swiperRef.current && swiperRef.current.swiper.autoplay) {
            swiperRef.current.swiper.autoplay.stop();
        }
    };
    const handleMouseleave = () => {
        if (swiperRef.current && swiperRef.current.swiper.autoplay) {
            swiperRef.current.swiper.autoplay.start();
        }
    };
    
      <Swiper {...swiperConfig} ref={swiperRef}>
      ...
      </Swiper>
      
      // 这里使用 handleMouseenter和handleMouseleave方法表现情况和直接使用pauseOnMouseEnter属性是一样的,hover轮播的时候不会立刻停止,hover离开的时候会立刻运动
      

实现运动运动还需要重置一下css样式

.swiper-wrapper {
    -webkit-transition-timing-function: linear;    /*之前是ease-out*/
    -moz-transition-timing-function: linear;
    -ms-transition-timing-function: linear;
    -o-transition-timing-function: linear;
    transition-timing-function: linear;
}

问题解决历程

首先了解到上面的点之后的改进代码 (应该还不是百分之百解决,swiperslide之间还有marginLeft间距问题,可能会影响鼠标hover那个slide的运动速度与原slide有一点不同,细节自己再斟酌一下)

  const handleMouseenter = () => {
        // 存放鼠标悬浮时的transform属性(行内属性)
        let nextTransForm = '';
        // 轮播图从暂停位置移动到原本应到的位置所用的时间
        let nextTime = 0;
        if (swiperRef.current && swiperRef.current.swiper.autoplay) {
            const swiperDom = swiperRef.current.swiper.el.children[0];
            // 轮播图原本应移动到的位置
            nextTransForm = swiperDom.style.transform;
            let nextTransPosition = parseInt(swiperDom.style.transform.split('translate3d(')[1].split('px')[0], 10);
            // 鼠标悬浮时时轮播图位置
            const nowTransPosition = swiperRef.current.swiper.getTranslate();
            // 计算轮播图从暂停位置移动到原本应到的位置所用的时间
            const swiperSlideWidth = swiperDom.children[0].getBoundingClientRect().width;
            nextTime = 6000 * (Math.abs(Math.abs(nextTransPosition) - Math.abs(nowTransPosition)) / swiperSlideWidth);
            setSwiperData({nextTransForm, nextTime});
            const instance = swiperRef.current.swiper.getTranslate();
            swiperRef.current.swiper.setTranslate(instance);
            swiperRef.current.swiper.autoplay.stop();
        }
    };
    const handleMouseleave = () => {
        const {nextTransForm, nextTime} = swiperData;
        if (swiperRef.current && swiperRef.current.swiper.autoplay) {
            const swiperDom = swiperRef.current.swiper.el.children[0];
            swiperDom.style.transform = nextTransForm;
            swiperDom.style.transitionDuration = nextTime + 'ms';
            swiperRef.current.swiper.autoplay.start();
        }
    };

思路来自blog.csdn.net/qq_45560350…