专栏首页web开发原生js实现简单移动端轮播图

原生js实现简单移动端轮播图

最近项目不是很忙,自己就用原生js写了一个简单的移动端轮播图的小demo,可实现自动轮播和手势滑动轮播,然后就把它记录到个人博客里。还有很多不足的地方,希望多多指出,以便改进。

1、代码部分

分为四个文件:

  slideshow.html

  slideshow.css

  base.js

  slideshow.js

1.1、slideshow.html

<!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">
    <title>移动端-轮播图</title>
    <link rel="stylesheet" href="slideshow.css">
</head>
<body>
<div class="layout">
    <div class="banner">
        <ul class="clearfix">
            <li><a href="#"><img src="images/l5.jpg"></a></li>
            <li><a href="#"><img src="images/l1.jpg"></a></li>
            <li><a href="#"><img src="images/l2.jpg"></a></li>
            <li><a href="#"><img src="images/l3.jpg"></a></li>
            <li><a href="#"><img src="images/l4.jpg"></a></li>
            <li><a href="#"><img src="images/l5.jpg"></a></li>
            <li><a href="#"><img src="images/l1.jpg"></a></li>
        </ul>
        <ul>
            <li class="now"></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
    </div>
</div>

<script src="base.js"></script>
<script src="slideshow.js"></script>
</body>
</html>

1.2、slideshow.css

*,
::before,
::after{
    padding: 0;
    margin: 0;
    -webkit-box-sizing: border-box;/*兼容移动端主流浏览器*/
    box-sizing: border-box;
    -webkit-tap-highlight-color: transparent;/*清除移动端点击高亮效果*/
}
body{
    font-family:Microsoft YaHei,sans-serif;/*移动端默认的字体*/
    font-size: 14px;
    color: #333;
}
ol,ul{
    list-style: none;
}
/*清除浮动*/
.clearfix::before,
.clearfix::after{
    content: "";
    display: block;
    height: 0;
    line-height: 0;
    visibility: hidden;
    clear: both;
}

.layout{
    width: 100%;
    max-width: 750px;
    min-width: 320px;
    margin: 0 auto;
    position: relative;
}
.banner{
    width: 100%;
    overflow: hidden;
    position: relative;
}
.banner ul:first-child{
    width: 1000%;
    -webkit-transform: translateX(-10%);
    transform: translateX(-10%);
}
.banner ul:first-child li{
    width: 10%;
    float: left;
}
.banner ul:first-child li a{
    display: block;
    width: 100%;
}
.banner ul:first-child li a img{
    width: 100%;
    display: block;
}
.banner ul:last-child{
    position: absolute;
    bottom: 6px;
    width: 100%;
    text-align: center;
}
.banner ul:last-child li{
    width: 6px;
    height: 6px;
    border: 1px solid #fff;
    border-radius: 50%;
    display: inline-block;
    margin-left: 10px;
}
.banner ul:last-child li:first-child{
    margin-left: 0;
}
.banner ul:last-child li.now{
    background: #fff;
}

1.3、base.js

/**
 * Created by libo on 2017/11/9.
 */

/*封装一些公用的事件或者公用的方法*/
/*定义的一个命名空间*/
window.my = {};
/*封装一个事件 过渡结束事件*/
my.transitionEnd = function(dom,callback){
    //1.给谁加事件
    //2.事件触发后处理什么业务
    if(!dom || typeof dom != 'object'){
        //没dom的时候或者不是一个对象的时候 程序停止
        return false;
    }
    dom.addEventListener('transitionEnd', function(){
        callback && callback();
    });
    dom.addEventListener('webkitTransitionEnd', function(){
        callback && callback();
    });
}

//封装一个tap事件
my.tap = function(dom,callback){
    if(!dom || typeof dom != 'object'){
        //没dom的时候或者不是一个对象的时候 程序停止
        return false;
    }

    var isMove = false; //是否滑动过
    var time = 0;   //刚刚触摸屏幕的事件  touchstart的触发事件

    dom.addEventListener('touchstart',function(){
        //记录触发这个事件的时间
        time = Date.now();  //时间戳 毫秒
    });
    dom.addEventListener('touchmove',function(){
        isMove = true;
    });
    window.addEventListener('touchend',function(e){
        //1.没有滑动过
        //2.响应事件在150ms以内   要求比click要响应快
        if(!isMove && (Date.now()-time)<150 ){
            callback && callback(e);
        }

        //重置参数
        isMove = false;
        time = 0;
    });

}

1.4、slideshow.js

/**
 * Created by libo on 2017/11/9.
 */
window.onload = function(){
    /*
     * 1.自动轮播  定时器  无缝衔接  动画结束瞬间定位
     * 2.点需要随着轮播的滚动改变对应的点  改变当前样式  当前图片的索引
     * 3.手指滑动的时候让轮播图滑动   touch事件  记录坐标轴的改变 改变轮播图的定位(位移css3)
     * 4.当滑动的距离不超过一定的距离的时候  需要吸附回去  过渡的形式去做
     * 5.当滑动超过了一定的距离  需要 跳到 下一张或者上一张  (滑动的方向) 一定的距离(屏幕的三分之一)
     * */

    var imageCount = 5; //页面中用来轮播的图片有5张不同的
    //轮播图大盒子
    var banner = document.querySelector('.banner');
    //图片的宽度
    var width = banner.offsetWidth;
    //图片盒子
    var imageBox = banner.querySelector('ul:first-child');
    //点盒子
    var pointBox = banner.querySelector('ul:last-child');
    //所有的点
    var points = pointBox.querySelectorAll('li');

    //公用方法
    //加过渡
    var addTransition = function(){
        imageBox.style.transition = "all 0.3s";
        imageBox.style.webkitTransition = "all 0.3s";/*做兼容*/
    };
    //清除过渡
    var removeTransition = function(){
        imageBox.style.transition = "none";
        imageBox.style.webkitTransition = "none";
    }
    //定位
    var setTranslateX = function(translateX){
        imageBox.style.transform = "translateX("+translateX+"px)";
        imageBox.style.webkitTransform = "translateX("+translateX+"px)";
    }

    //功能实现
    //自动轮播  定时器  无缝衔接  动画结束瞬间定位
    var index = 1;
    var timer = setInterval(function(){
        index++ ;   //自动轮播到下一张
        //改变定位  动画的形式去改变  transition transform translate
        addTransition();    //加过渡动画
        setTranslateX(-index * width);  //定位
    },3000);

    //等过渡结束之后来做无缝衔接
    my.transitionEnd(imageBox, function(){
        //处理事件结束后的业务逻辑
        if(index > imageCount ){
            index = 1;
        }else if(index <= 0){
            index = imageCount;
        }
        removeTransition(); //清除过渡
        setTranslateX(-index * width);  //定位
        setPoint(); //设置底部显示当前图片对应的圆角
    });

    //改变当前样式  当前图片的索引
    var setPoint = function(){
        //清除上一次的now
        for(var i = 0 ; i < points.length ; i++){
            points[i].className = " ";
        }
        //给图片对应的点加上样式
        points[index-1].className = "now";
    }

    /*
     手指滑动的时候让轮播图滑动   touch事件  记录坐标轴的改变 改变轮播图的定位(位移css3)
     当滑动的距离不超过一定的距离的时候  需要吸附回去  过渡的形式去做
     当滑动超过了一定的距离  需要 跳到 下一张或者上一张  (滑动的方向) 一定的距离(屏幕的三分之一)
     */
    //touch事件
    var startX = 0; //记录起始  刚刚触摸的点的位置 x的坐标
    var moveX = 0;  //滑动的时候x的位置
    var distanceX = 0;  //滑动的距离
    var isMove = false; //是否滑动过

    imageBox.addEventListener('touchstart', function(e){
        clearInterval(timer);   //清除定时器
        startX = e.touches[0].clientX;  //记录起始X
    });

    imageBox.addEventListener('touchmove',function(e){
        moveX = e.touches[0].clientX;   //滑动时候的X
        distanceX = moveX - startX; //计算移动的距离
        //计算当前定位  -index*width+distanceX
        removeTransition(); //清除过渡
        setTranslateX(-index * width + distanceX);  //实时的定位
        isMove = true;  //证明滑动过
    });

    //在模拟器上模拟的滑动会有问题 丢失的情况  最后在模拟器的时候用window
    imageBox.addEventListener('touchend', function(e){
        // 滑动超过 1/3 即为滑动有效,否则即为无效,则吸附回去
        if(isMove && Math.abs(distanceX) > width/3){
            //5.当滑动超过了一定的距离  需要 跳到 下一张或者上一张  (滑动的方向)*/
            if(distanceX > 0){  //上一张
                index --;
            }
            else{   //下一张
                index ++;
            }
        }
        addTransition();    //加过渡动画
        setTranslateX(-index * width);    //定位

        if(index > imageCount ){
            index = 1;
        }else if(index <= 0){
            index = imageCount;
        }
        setPoint();

        //重置参数
        startX = 0;
        moveX = 0;
        distanceX = 0;
        isMove = false;
        //加定时器
        clearInterval(timer);   //严谨 再清除一次定时器
        timer= setInterval(function(){
            index++ ;  //自动轮播到下一张
            addTransition();    //加过渡动画
            setTranslateX(-index * width);    //定位
        },3000);
    });
};

2、效果

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • echarts2简单笔记

    用户1174387
  • 树结构数据的展示和编辑-zTree树插件的简单使用

    最近在项目当中遇到一个需求,需要以树结构的方式展示一些数据,并可对每一个树节点做内容的编辑以及树节点的添加和删除,刚好听说有zTree这个插件可以实现这样的需求...

    用户1174387
  • 自实现PC端jQuery版轮播图

    最近其他项目不是很忙,被安排给公司的官网项目做一个新的页面(之前没接触公司官网项目),其中有一个用到轮播图的地方,最开始想直接用swiper.js插件实现就好了...

    用户1174387
  • 在同一行布局的技巧 原

    例如上面的布局,我们可以使用里面元素浮动,外面的div高度为0的特点来布局,使2个div重叠在一起

    tianyawhl
  • JavaScript面向对象精要(二)

    构造函数就是用new创建对象时调用的函数。使用构造函数的好处在于所有用同一个构造函数创建的对象都具有同样的属性和方法。

    奋飛
  • 对 COM 组件的调用返回了错误 HRESULT E_FAIL。

    win7系统,用c#调用Interop.SHDocVw.dll时,报了个对“ COM 组件的调用返回了错误 HRESULT E_FAIL”的错误。网上...

    明年我18
  • Spring Boot---(8)SpringBoot整合mybatis

    注意:在程序的启动类上,一定要加上扫描dao包的注解:@MapperScan("持久层路径")否则会报错:

    IT云清
  • 融了1000万,只为让它们好好吃饭!

    镁客网
  • Solr入门

    本文主要介绍solr的基本用法。首先,我们从Apache官网下载solr的二进制分发包,然后解压缩文件。安装完成后,我们将启动solr服务器,并通过浏览器访问s...

    栋先生

扫码关注云+社区

领取腾讯云代金券