问题表现
我想要实现如下自动轮播新闻展示效果
鼠标在轮播上悬浮则轮播图停止自动轮播,鼠标离开则继续自动轮播
我定义的生成swiper对象的方法
createSwiper() {
this.swiper = new Swiper(".swiper-container_2", {
autoplay: {//自动切换
delay: 0,//自动切换时间间隔
stopOnLastSlide: false,//切换到最后一个slide时 不会 自动停止
disableOnInteraction: false,//用户操作swiper后自动切换不会停止 每次都会重新启动
},
allowTouchMove: false,//不允许触摸滑动
loop: true,//开启环路
speed: 5000,//切换速度
slidesPerView: "auto",//设置slider容器能够同时显示的slide的数量 设为auto时可自定义slide的宽度
spaceBetween: 30,//设置slide之间的距离
centeredSlides: true,//当slide的总数小于slidesPerView时,slide居中
watchSlidesProgress: true,
preventClicks: false,//当swiper在触摸时不会阻止默认事件
preventClicksPropagation: false,//当拖动swiper时阻止click时间
});
this.swiper.el.onmouseover = function () {
this.swiper.autoplay.stop();
};
this.swiper.el.onmouseout = function () {
this.swiper.autoplay.start();
};
},
注:
想要实现无缝切换的效果 需要添加css属性
/deep/.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;
margin: 0 auto;
}
但我发现当我的鼠标悬浮在轮播图上时,总会过一段时间再停止,而鼠标离开则会立即开始。
本以为是speed的原因,因为改变speed会有不同的效果,但实际上仍然会有延迟,只是改变了轮播从运动到停止的时间间距。
问题原因
speed值表示每张轮播图之间的切换时长,而鼠标悬浮时,如果轮播图正在切换不会立即停止,而是要等到这次切换完才会停止。而我要实现的效果,speed设置的比较长,所以鼠标放上去要等待的切换动画时间长,延迟效果就会变得很明显。
问题解决
完全不算解决…实际上swiper提供的自带方法完全无法解决我的问题,而我要实现的效果从某种程度上来说也不算是轮播图,所以最后我选择不用swiper来实现,而是用ul列表来展示,写个定时器不停改变ul的margin-left。
PS:最后这个解决办法也不算真正的解决,看到这篇文章的小伙伴如果有更好的办法,可以分享一下吗?我总觉得还有一线希望…
博主后来因为一些原因得重新回来解决这个问题,还是得用轮播图实现(呜呜呜),不死心地再次百度,终于是功夫不负有心人地找到了一个解决办法,下面是解决思路:
之前说问题的原因在于swiper的autoplay.stop()方法只能暂停下一次的切换,而这次的切换还是得进行完,因此会有一个看起来延迟的效果
打开控制台,能看到swiper-wrapper上的transform属性规定了这次切换后轮播图会到的位置,那么如果我把这个属性的值直接改为当前轮播图的位置是不是就可以实现暂停了呢?没毛病,鼠标移开后,先把之前未完成的切换过程进行完,再把一切恢复原样就OK啦
下面是实现代码:
// 存放鼠标悬浮时的transform属性(行内属性)
let nextTransForm = "";
// 轮播图从暂停位置移动到原本应到的位置所用的时间
let nextTime = 0;
// 鼠标悬浮暂停轮播
this.swiper.el.onmouseenter = function () {
nextTransForm = document
.getElementsByClassName("swiper-container_2")[0]
.getElementsByClassName("swiper-wrapper")[0].style.transform;
// 轮播图原本应移动到的位置
let nextTransPosition =
-1 *
parseInt(
document
.getElementsByClassName("swiper-container_2")[0]
.getElementsByClassName("swiper-wrapper")[0]
.style.transform.split("translate3d(")[1]
.split("px")[0]
);
// 鼠标悬浮时时轮播图位置
let nowTransPosition =
-1 *
parseInt(
window
.getComputedStyle(
document
.getElementsByClassName("swiper-container_2")[0]
.getElementsByClassName("swiper-wrapper")[0],
false
)
["transform"].split("1, ")[2]
.split(",")[0]
);
// 存放鼠标悬浮时轮播图的真实transform属性(非行内属性)
let nowTransForm = window.getComputedStyle(
document
.getElementsByClassName("swiper-container_2")[0]
.getElementsByClassName("swiper-wrapper")[0],
false
)["transform"];
// 计算轮播图从暂停位置移动到原本应到的位置所用的时间(370是我自定义的每个slide的宽度)
nextTime = 5500 * ((nextTransPosition - nowTransPosition) / 370);
// 改变行内transform属性
document
.getElementsByClassName("swiper-container_2")[0]
.getElementsByClassName(
"swiper-wrapper"
)[0].style.transform = nowTransForm;
// 不写也没关系
document
.getElementsByClassName("swiper-container_2")[0]
.getElementsByClassName(
"swiper-wrapper"
)[0].style.transitionDuration = "0ms";
this.swiper.autoplay.stop();
};
// 鼠标离开轮播图开始轮播
this.swiper.el.onmouseleave = function () {
console.log('leave'+nextTransForm)
// 恢复原样
document
.getElementsByClassName("swiper-container_2")[0]
.getElementsByClassName(
"swiper-wrapper"
)[0].style.transform = nextTransForm;
document
.getElementsByClassName("swiper-container_2")[0]
.getElementsByClassName("swiper-wrapper")[0]
.style.transitionDuration = nextTime+"ms";
this.swiper.autoplay.start();
};