css

Es6+jquery制作无缝轮播图

Posted by WWJ on June 22, 2018

ES6+JQuery制作无缝轮播

原理

在第一张图片的前面添加最后一张图片,在最后一张图片的后面增加第一张图片(作为无缝切换时的辅助图片)

  • 向上切换 enter image description here 黄色为当前可见的图片,当当前可见的图片为真实的第一张且继续向上切换时,这个时候其实我们想要看到的是索引为3的图片(即真实的第3张图片),所以我们应该将整个轮播的容器向左平移4个图片的宽度,这个时候索引为4的赋值图片就起作用了,如果没有这张辅助图片的话,再向上切换就会出现空白,放置这张图片就避免了这种情况
  • 向下切换 enter image description here 当当前可见图片是真实的第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’ |