一、实现效果
二、样式与结构代码
html:
<div class="item center"><div id="certify" class="col-md-12"><div class="swiper-container"><div class="swiper-wrapper"><div class="swiper-slide"><div class="com_wrap"><!-- 内部结构省略 --></div></div></div><div class="swiper-pagination"></div></div></div></div>
css:
#certify {position: relative;width: 100%;margin: 72px auto 0;padding-bottom: 117px;
}#certify .swiper-slide {width: 945px;height: 304px;background: #fff;position: relative;border-radius: 8px;
}#certify .swiper-slide img {display: block;height: 150px;margin-bottom: 20px;
}#certify .swiper-pagination {position: relative !important;margin-top: 30px;height: 10px;
}#certify .swiper-pagination-bullets .swiper-pagination-bullet-active {border: 3px solid #00aadc;background-color: #fff;
}#certify .swiper-button-prev {left: 0;width: 80px;font-size: 30px;text-align: center;line-height: 80px;height: 80px;background: inherit;background-color: rgba(242, 242, 242, 1);border: none;
}#certify .swiper-button-next {right: 0;font-size: 30px;text-align: center;line-height: 80px;width: 80px;height: 80px;background: inherit;background-color: rgba(242, 242, 242, 1);border: none;
}/* 轮播项样式 */
#certify .swiper-container .swiper-wrapper {display: flex;align-items: center;
}
三、预备知识
- swiper和slide都有其自身的progress(进度)值
swiper的progress不用特别设置去开启,而slide的progress则需要设置watchSlidesProgress为true来计算每个slide的进度值。
这个概念或许很抽象,但从文档中的阐述我们可以很直观地理解这个进度值究竟为何物。
对于swiper而言,活动的slide在最左边时progress为0,活动的slide在最右边时为1,其他情况平分。假如有6个slide,当活动的是第三个时swiper的progress属性是0.4,当活动的是第五个时swiper的progress属性是0.8。
而对于每个slide而言,活动块slide的progress为0,其他的依次减1。例:如果一共有6个slide,活动块slide是第三个,那么从第一个到第六个的progress属性分别是:2、1、0、-1、-2、-3。
- 开启 loop 选项时,Swiper 会对原始的 slide 进行复制来实现循环滚动效果
具体来说,Swiper 会在每次滚动时在轮播列表的开头和结尾分别复制一个 slide,以创建一个无限循环的效果。 - 设置loopedSlides参数,它会影响 Swiper.js 在实际的循环滚动过程中生成的虚拟 slide 数据的个数
这个参数指定了在循环滚动中每个原始 slide 周围额外生成的虚拟 slide 数量。
例如当我设置loopedSlides为2时:
(为了方便查看效果,我在监听progress变化的函数中让它遍历slide时输出了当前的slide序列号及其对应的progress值,且我实际上插入dom结构的slide数量只有三个)
由图我们知道目前遍历到的slide数量变成了7个,可见它在原始的slide列表前后都复制了两个虚拟slide。
四、swiper3和swiper4-8的版本实现
// swiper3var mySwiper = new Swiper('.swiper-container', {// 开启这个参数来计算每个slide的progress(进度、进程),Swiper的progress无需设置即开启watchSlidesProgress: true,/* 设置slider容器能够同时显示的slides数量(carousel模式)。可以设置为数字(可为小数,小数不可loop),或者 'auto'则自动根据slides的宽度来设定数量。loop模式下如果设置为'auto'还需要设置另外一个参数loopedSlides。这里不要设置成你想显示的slide个数,因为他会给每个slide平分宽度*/slidesPerView: 'auto',// 设定为true时,活动块会居中,而不是默认状态下的居左。centeredSlides: true,//在loop模式下使用slidesPerview:'auto',还需使用该参数设置所要用到的loop个数loopedSlides: 3,autoplay: 3000,loop: true,/* 用户操作swiper之后,是否禁止autoplay。默认为true:停止。如果设置为false,用户操作swiper之后自动切换不会停止,每次都会重新启动autoplay。操作包括触碰,拖动,点击pagination等。*/autoplayDisableOnInteraction: true,pagination: ".swiper-pagination",paginationClickable: true,// 回调函数,当Swiper的progress被改变时执行。接受Swiper实例和progress作为参数(可选)。onProgress: function (swiper, progress) {for (i = 0; i < swiper.slides.length; i++) {var slide = swiper.slides.eq(i);// 获取当前slide的进度值var slideProgress = swiper.slides[i].progress;// 用于调整滑动时slide过渡效果的基准值modify = 1;if (Math.abs(slideProgress) > 1) {modify = (Math.abs(slideProgress) - 1) * 0.3 + 1;}/*这里的699设置成你实际需要的活动slide的宽度由此来调整其他slide的水平偏移量,而活动slide由于progress为0,它不会有水平偏移*/translate = slideProgress * modify * 699 + 'px';/*缩放比例根据你自己的需要调整 我这里设置活动slide的相邻两个slide缩放比例为成0.75*/scale = 1 - Math.abs(slideProgress) / 4;//堆叠顺序zIndex = 999 - Math.abs(Math.round(10 * slideProgress));slide.transform('translateX(' + translate + ') scale(' + scale + ')');slide.css('zIndex', zIndex);slide.css('opacity', 1);if (Math.abs(slideProgress) > 0.5) {slide.css('opacity', 0.8);}/* 根据活动的slide的progress为0,其他依次减1的特性来设置透明度/父元素overflow从而控制slider容器实际显示的slide个数【直接用slidesPerView会让每个slide均分容器大小*/if (Math.abs(slideProgress) > 1.5) {slide.css('opacity', 0);}}},/*这个回调函数会在每次轮播项切换时触发,用于为每个轮播项设置过渡效果在使用 setTransition 回调函数时,Swiper 会自动计算并传递合适的过渡时间,以确保轮播项的切换具有平滑的过渡效果。因此可以在回调函数中直接使用传递的 transition 参数,也可以自己定义过渡效果*/onSetTransition: function (swiper, transition) {for (var i = 0; i < swiper.slides.length; i++) {//获取当前slidevar slide = swiper.slides.eq(i)/*通过jquery设置该slide的transition属性,这是一个css属性,用于控制过渡效果,这里控制的是过渡时间 体现过渡效果的延迟*/slide.transition(transition);}},})
另外,之所以要给每个轮播项slide自定义过渡效果,这是因为默认情况下,Swiper 的轮播项切换是通过 CSS 过渡属性实现的,它们没有指定过渡时间,因此切换是即时的。如果不用他计算好的transition值,那么看起来的效果就相当于slide.transition(0);
//swiper4-8
const mySwiper = new Swiper('.swiper', {watchSlidesProgress: true,slidesPerView: 'auto',centeredSlides: true,loopedSlides: 3,autoplay: { delay: 3000 },loop: true,autoplayDisableOnInteraction: true,on: {progress: function(swiper, progress) {for (let i = 0; i < swiper.slides.length; i++) {const slide = swiper.slides[i];const slideProgress = swiper.slides[i].progress;let modify = 1;if (Math.abs(slideProgress) > 1) {modify = (Math.abs(slideProgress) - 1) * 0.3 + 1;}const translate = slideProgress * modify * 699 + 'px';const scale = 1 - Math.abs(slideProgress) / 4;const zIndex = 999 - Math.abs(Math.round(10 * slideProgress));slide.style.transform = `translateX(${translate}) scale(${scale})`;slide.style.zIndex = zIndex;slide.style.opacity = 1;if (Math.abs(slideProgress) > 0.5) {slide.style.opacity = 0.8;}if (Math.abs(slideProgress) > 1.5) {slide.style.opacity = 0;}}},setTransition: function (transition) {for (var i = 0; i < this.slides.length; i++) {var slide = this.slides.eq(i)slide.transition(transition);}}},});
本文参考了
swiper横向轮播——阶梯式滚动轮播
slide ——首尾相接の平滑切换效果,
并在此基础上得出了自己的理解与总结。
如有错误,请指正。