1

swiper.js

(function(w){
    function swiper(options) {
        //从options取出想要数据
        var swiper = options.el; //获取包裹元素
        var pagination = options.pagination || false;  //是否有高亮圆点,默认无,如需要自行设置元素
        var isAutoPlay = options.isAutoPlay || false;   //是否自动播放,默认不自动播放
        var duration = options.duration || 5000;  //自动播放时间间隔

        //给swiper添加类型
        swiper.classList.add('swiper');

        //获取元素
        var swiperWrapper = swiper.querySelector('.swiper-wrapper');
        var swiperItems = swiper.getElementsByClassName('swiper-item');
        var itemLength = swiperItems.length; //每克隆之前,数量存储
        var index = itemLength;  //当前显示的图片的索引

        var isFirstTouchMove = true; //标记是否是第一次触发touchmove
        var isHorizontal = true; //标记是否是水平滑动

        //如果用户指定了 分页小圆点
        if (pagination) {
            //根据swiperItem的数量,创建子元素
            for (var i = 0; i < itemLength; i ++) {
                var span = document.createElement('span');
                pagination.appendChild(span);
            }
            //给pagination添加类
            pagination.classList.add('paginations');
            var paginationItems = pagination.querySelectorAll('span');
        }

        //把所有的图片都克隆一份
        swiperWrapper.innerHTML += swiperWrapper.innerHTML;

        //动态的设置swiperWrapper的宽度
        swiperWrapper.style.width = swiperItems.length * 100 + '%';
        [].forEach.call(swiperItems, function(swiperItem){
            swiperItem.style.width = 100 / swiperItems.length + '%';
        });

        //设置起始位置 初始化位置
        setSwiper(index);

        //触摸开始
        swiper.addEventListener('touchstart', function(event){
            //取消过渡效果
            swiperWrapper.style.transition = 'none';

            //判断是否是临界点
            if (index === 0) {
                index = itemLength;
                setSwiper(index);
            } else if (index === swiperItems.length - 1) {
                index = itemLength - 1;
                setSwiper(index);
            }

            //获取触点对象
            var touch = event.changedTouches[0];
            // 获取触点的起始位置 x方向
            this.startX = touch.clientX;
            // 获取触点的起始位置  y方向
            this.startY = touch.clientY;
            //获取swiperWrapper元素的起始位置
            this.eleX = transformCss(swiperWrapper, 'translateX');
            //计算开始的时间
            this.startTime = Date.now();
            //初始化dstX
            this.dstX = 0;
            //重新初始化 两个标记
            isFirstTouchMove = true;
            isHorizontal = true;

            //清除定时
            if (isAutoPlay) {
                clearInterval(intervalId);
            }
        });

        //触摸移动
        swiper.addEventListener('touchmove', function(event){
            //如果不是水平滑动
            if (!isHorizontal) {
                return;
            }

            //获取触点对象
            var touch = event.changedTouches[0];
            //获取触点的结束位置,x方向/y方向
            var endX = touch.clientX, endY = touch.clientY;
            //计算手指滑动的距离 水平方向
            this.dstX = endX - this.startX;
            //计算垂直方向手指滑动距离
            var dstY = endY - this.startY;

            //判断是否是第一次触发touchmove
            if (isFirstTouchMove) {
                // 设置标记,已经不是第一次了
                isFirstTouchMove = false;
                // 判断用户水平滑动的距离大还是垂直滑动的距离大
                //如果垂直滑动的距离大 执行垂直的逻辑
                if (Math.abs(dstY) > Math.abs(this.dstX)) {
                    this.dstX = 0;
                    isHorizontal = false; //标记不是水平滑动
                    return;
                }
            }

            //根据滑动的距离,计算swieprSwiper的位置
            transformCss(swiperWrapper, 'translateX', swiper.eleX + swiper.dstX);

            //阻止默认行为
            event.preventDefault();
        });

        //触摸结束
        swiper.addEventListener('touchend', function(){
            //计算结束时间
            var endTime = Date.now();
            //计算一个完整动作(从touchstart到touchend)所需时间
            var dstTime = endTime - this.startTime;

            // 判断用户是否是快速滑动
            if (dstTime < 300) { //说明用户快
                if (this.dstX < 0) { //下一张
                    index ++;
                } else if (this.dstX > 0) {
                    index --;
                }
            } else {
                //计算要切换到的index值 直接取反
                index = -(Math.round(transformCss(swiperWrapper, 'translateX') / swiper.clientWidth));
            }

            //添加过渡效果
            swiperWrapper.style.transition = 'transform .5s';

            //进行切换
            setSwiper(index);

            // 重新开启定时
            if (isAutoPlay) {
                intervalId = setInterval(runSwiper, duration);
            }
        });

        // 给swiperWrapp监听 transitionend事件
        swiperWrapper.addEventListener('transitionend', function(){
            if (index >= swiperItems.length - 1) {  //如果切换到了最后一张
                //设置index变为上一组的最后一张
                index = itemLength - 1;
                //快速切换到index的位置
                swiperWrapper.style.transition = 'none';
                setSwiper(index);
            }
        });


        //定时器开始定时播放
        if (isAutoPlay) {
            var intervalId = setInterval(runSwiper, duration);
        }

        // 定时执行函数
        function runSwiper(){
            //索引自增
            index ++;
            //添加过渡效果
            swiperWrapper.style.transition = 'transform .5s';
            //执行切换
            setSwiper(index);
        }
        /**
         * 实现图片和小圆点的切换
         * @param m 要切换的索引
         */
        function setSwiper(m) {
            // 根据index 设置swiperSwiper的位置
            transformCss(swiperWrapper, 'translateX', -m * swiper.clientWidth);

            //小圆点 切换; 排他操作
            if (pagination) {
                paginationItems.forEach(function(paginationItem){
                    paginationItem.classList.remove('actived');
                });
                paginationItems[m%itemLength].classList.add('actived');
            }
        }
    }

    //暴露
    w.swiper = swiper;
})(window);

swiper.css

.swiper {
  position: relative;
  width: 100%;
  overflow: hidden;
}
.swiper-wrapper {
  width: 500%;
  display: flex;
}
.swiper-item {
  width: 20%;
}
.swiper-item img {
  width: 100%;
  display: block;
}
.paginations {
  position: absolute;
  left: 0;
  bottom: 8px;
  width: 100%;
  text-align: center;
  font-size: 0;
}
.paginations span {
  margin: 0 2px;
  display: inline-block;
  width: 10px;
  height: 10px;
  background-color: #999;
  border-radius: 50%;
}
.paginations span.actived {
  background-color: deeppink;
}

使用案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0,viewport-fit:cover">
    <title>移动端轮播图</title>
    <link rel="stylesheet" href="css/swiper.css">
    <style>
        *{
            margin: 0;
            padding: 0;
            list-style: none;
        }
    </style>
</head>
<body>
    <div id="app">
        <!--轮播图-->
        <div class="swiper">
            <ul class="swiper-wrapper">
                <li class="swiper-item"><img src="img/1.jpg" alt="图片"></li>
                <li class="swiper-item"><img src="img/2.jpg" alt="图片"></li>
                <li class="swiper-item"><img src="img/3.jpg" alt="图片"></li>
                <li class="swiper-item"><img src="img/4.jpg" alt="图片"></li>
                <li class="swiper-item"><img src="img/5.jpg" alt="图片"></li>
            </ul>
            <div class="paginations"></div>  //自行设置高亮圆点包裹元素
        </div>
    </div>
    <script src="js/transformcss.js"></script>
    <script src="js/swiper.js"></script>
    <script>
        //轮播图
        (function() {
            //调用插件
            swiper({
                el: document.querySelector('.swiper'), //必须指定,指定swiper的包裹元素
                pagination: document.querySelector('.paginations'), //需有小圆点,指定元素
                isAutoPlay: true,  //是否自动播放,默认不自动播放
                duration: 5000 //定时器事件间隔
            });
        })()
    </script>
</body>
</html>

注:文中的轮播效果是建立在 transformcss.js文件基础上的,因此引入 swiper.js前,需先将 transformcss.js 引入。
transformcss.js 文件请查看上一篇文章: 封装transfrom函数。


如果对您有帮助的话,点击 http://learn.fuming.site/ 学习更多!


捕猹少年闰土
42 声望0 粉丝