ES6+JQuery制作无缝轮播
原理
在第一张图片的前面添加最后一张图片,在最后一张图片的后面增加第一张图片(作为无缝切换时的辅助图片)
- 向上切换 黄色为当前可见的图片,当当前可见的图片为真实的第一张且继续向上切换时,这个时候其实我们想要看到的是索引为3的图片(即真实的第3张图片),所以我们应该将整个轮播的容器向左平移4个图片的宽度,这个时候索引为4的赋值图片就起作用了,如果没有这张辅助图片的话,再向上切换就会出现空白,放置这张图片就避免了这种情况
- 向下切换 当当前可见图片是真实的第3张且继续向下切换时,这个时候其实我们想要看到的是索引为1的图片(即真实的第一张图片),那么这个时候我们就应该将整个轮播的容器的left值置为0,这个时候索引为0的辅助图片起的作用同上,即避免再切换的时候出项空白
代码
<div class="J_slider_wrap" id="J_slider_wrap">
<i class="J_prev ifont"><</i>
<i class="J_next ifont">></i>
<ul class="J_slider">
<li class="J_slider_item">
<a href="http://">
<img src="http://image.ibb.co/fguWh8/mockup.jpg" width="510" height="270" alt="2014春装新品首发">
</a>
</li>
<li class="J_slider_item">
<a href="http://">
<img src="http://image.ibb.co/fguWh8/mockup.jpg" width="510" height="270" alt="2014春装新品首发">
</a>
</li>
<li class="J_slider_item">
<a href="http://">
<img src="http://image.ibb.co/fguWh8/mockup.jpg" width="510" height="270" alt="2014春装新品首发">
</a>
</li>
<li class="J_slider_item">
<a href="http://">
<img src="http://image.ibb.co/fguWh8/mockup.jpg" width="510" height="270" alt="2014春装新品首发">
</a>
</li>
<li class="J_slider_item">
<a href="http://">
<img src="http://image.ibb.co/fguWh8/mockup.jpg" width="510" height="270" alt="2014春装新品首发">
</a>
</li>
</ul>
<ol class="J_trigger">
<li class="J_trigger_item active">1</li>
<li class="J_trigger_item">2</li>
<li class="J_trigger_item">3</li>
</ol>
</div>
ul, ol, p{
padding: 0;
margin: 0
}
li{
list-style: none;
}
.J_slider_wrap{
margin: 200px auto;
width: 510px;
height: 270px;
overflow: hidden;
position: relative;
}
.J_slider_wrap .ifont {
display: block;
opacity: 0;
position: absolute;
z-index: 10;
top: 50%;
margin-top: -15px;
height: 30px;
width: 20px;
line-height: 30px;
color: #fff;
background-color: #585656;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
transition: all 0.3s ease-in;
}
.J_slider_wrap .ifont:hover{
background-color: #000;
}
.J_slider_wrap .J_prev{
left: -2px;
}
.J_next{
right: -2px;
}
.J_slider{
display: flex;
height: 100%;
width: 2550px;
position: absolute;
left: -510px;
}
.J_slider_wrap:hover .ifont{
opacity: 1;
}
.J_slider .J_slider_item {
display: inline-block;
width: 510px;
height: 100%;
}
.J_trigger{
position: absolute;
right: 10px;
bottom: 10px;
display: flex;
}
.J_trigger .J_trigger_item {
width: 20px;
height: 20px;
background-color: #fff;
margin-left: 8px;
border: 1px solid #b5a395;
color: #e2b536;
text-align: center;
cursor: pointer;
}
.J_trigger .active{
background-color: #b5a395;
color: #fff;
}
const $body = $('body')
class Carousel {
constructor(config) {
this.defaultConfig = {
isLoop: true,//默认循环播放
isAuto: true,//默认自动播放
isClick: false,
duration: 500,//轮播图片之间切换的时间间隔
interval: 2000,//自动播放的时间间隔
curIdx: 1,//当前播放图片的索引
curTriggerCls: 'active',//当前活跃的按钮类名
timer: null//定时器
}
config = $.extend({}, this.defaultConfig, config)
this.config = config
this.$prevSlt = this.config.prevSlt
this.$nextSlt = this.config.nextSlt
this.$slider_wrap = $(this.config.slider_wrap)
this.$slider = $(this.config.slider)
this.$slider_items = $(this.config.slider_items)
this.$trigger = $(this.config.trigger)
this.$trigger_items = $(this.config.trigger_items)
this.bindEvent()
this.autoPlay()
}
bindEvent() {
this.$slider_wrap.on('click', this.$prevSlt, () => {
//防止频繁点击
if (this.config.isClick) return
this.config.isClick = true
window.setTimeout(() => { this.prev() }, 1000)
});
this.$slider_wrap.on('click', this.$nextSlt, () => {
//防止频繁点击
if (this.config.isClick) return
this.config.isClick = true
window.setTimeout(() => { this.next() }, 1000)
})
if (this.config.isAuto) {
this.$slider_wrap.on('mouseenter', `${this.$prevSlt}, ${this.$nextSlt}, li`,
() => {
this.stop()
return false
}
);
this.$slider_wrap.on('mouseleave', `${this.$prevSlt}, ${this.$nextSlt}, li`,
() => {
this.autoPlay();
return false;
},
);
}
this.$trigger.on('click', this.config.trigger_items, (e) => {
e = e || window.event
let idx = $(e.target).index()
this.triggerOn(idx + 1)
this.animate(idx + 1)
})
}
stop() {
window.clearInterval(this.timer)
this.timer = null
}
autoPlay() {
this.timer = window.setInterval(() => {
this.next()
}, 2000)
if (!this.config.isAuto) this.stop()
}
prev() {
this.go(this.config.curIdx - 1)
this.config.isClick = false
}
next() {
this.go(this.config.curIdx + 1)
this.config.isClick = false
}
go(idx) {
if (this.config.isLoop) {
if (idx < 1) {
idx = this.$slider_items.length - 2
this.$slider.css('left', -$(this.$slider_items[0]).width() * 4)
}
if (idx > this.$slider_items.length - 2) {
idx = 1
this.$slider.css('left', 0)
}
} else if (idx < 1 || idx > this.$slider_items.length - 2) return
if (idx === this.config.curIdx) return
this.config.curIdx = idx
this.triggerOn(idx)
this.animate(idx)
}
triggerOn(idx) {
this.$trigger_items.removeClass(this.config.curTriggerCls)
$(this.$trigger_items[idx - 1]).addClass(this.config.curTriggerCls)
}
animate(idx) {
this.$slider.animate({
left: -idx * $(this.$slider_items[0]).width()
}, this.config.duration)
}
}
$(() => {
let carousel = new Carousel({
slider_wrap: '.J_slider_wrap',
slider: '.J_slider',
slider_items: '.J_slider_item',
trigger: '.J_trigger',
trigger_items: '.J_trigger_item',
prevSlt: '.J_prev',
nextSlt: '.J_next',
isAuto: false,
// isLoop:false
})
});
参数说明
| 参数 | 说明 | 类型 | 默认值 | | —— | —— | —— | —– | | isLoop| 是否循环播放 | boolean | true | | isAuto | 是否自动播放| boolean | true | | duration| 图片切换的时间间隔 | number | 500ms | | interval| 自动播放的时间间隔 | number | 1000ms | | curTriggerCls| 当前活跃的焦点 | string | ‘active’ | | slider_wrap| 轮播图最外层容器类名 | string | ‘.J_slider_wrap’ | | slider| 用来包裹图片的容器类名 | string | ‘.J_slider’ | | slider_items| 每张图片的类名 | string | ‘J_slider_item’ | | trigger| 用来包裹每个焦点的容器的类名 | string | ‘J_trigger’ | | trigger_items| 每个焦点的类名 | string | ‘J_trigger_item’ | | prevSlt| 向上切换的按钮类名 | string | ‘.J_prev’ | | nextSlt| 向下切换的按钮类名 | string | ‘J_next’ |