前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >移动端轮播图笔记

移动端轮播图笔记

原创
作者头像
帅的一麻皮
修改2020-05-07 10:11:56
2.4K0
修改2020-05-07 10:11:56
举报

1.触屏事件

1.1触屏事件概述

移动端浏览器兼容性好,我们不需要考虑以前JS的兼容问题,可以放心使用原生JS书写效果,但是移动端也有自己独特的地方,比如触屏事件touch(也叫触摸事件),Android和IOS都有。

touch对象代表一个触摸点,触摸点可能是一根手指,也可能是一根笔。触屏事件可以相应用户手指对屏幕或者触控板操作

常见的触屏事件:

  • 1.touchstart:手指触摸到一个DOM元素时触发
  • 2.touchmove:手指在一个DOM元素上滑动时触发
  • 3.touchend:手指从一个DOM元素上移开时触发

1.2触摸事件对象(TochEvent)

TouchEvent是一类描述手指在触摸平面(触摸屏、触摸板等)的状态变化的事件。这类事件用于描述一个或者多个触点,使开发者可以检测触点的移动,触点的增加和减少,等等

touchstart、touchmove、touchend三个时间都会各自有事件对象

触摸事件对象终点我们看三个常见对象列表

  • 1.touches:正在触摸屏幕的所有手指的一个列表
  • 2.targetTouches:正在触摸当前DOM元素上的手指的一个列表(最常使用
  • 3.changeTouches:手指状态发生了改变的列表,从无到有,从有到无变化

1.3移动端拖动元素

1.touchstart、touchmove、touchend可以实现拖动元素

2.但是拖动元素需要当前手指的坐标值,我们可以使用targetTouches[0]里面的pageXpageY

3.移动端拖动的原理:手指移动中,计算出手指移动的距离。然后用盒子原来的位置+手指移动的距离

4.手指移动的距离:手指滑动中的位置减去手指刚开始触摸的位置

拖动元素三部曲:

(1)触摸元素touchstart:获取手指初始坐标,同时获得盒子原来的位置

(2)移动手指touchmove:计算手指的滑动距离,并且移动盒子

(3)离开手指touchend

注意:手指移动也会触发滚动屏幕所以这里要阻止默认的屏幕滚动e.preventDefault();

2.移动轮播案例

三张图片进行轮播,需要将第一张克隆一张到最后,最后一张克隆一张到第一张,大概意思为下图:

html布局

<div class="container">
        <div class="banner clearfix">
            <ul class="clearfix">
                <li><a href="#"><img src="images/ban3.jpg" alt=""></a></li>
                <li><a href="#"><img src="images/ban1.jpg" alt=""></a></li>
                <li><a href="#"><img src="images/ban2.jpg" alt=""></a></li>
                <li><a href="#"><img src="images/ban3.jpg" alt=""></a></li>
                <li><a href="#"><img src="images/ban1.jpg" alt=""></a></li>
            </ul>
            <!-- 小圆点 -->
            <ol>
                <li class="current"></li>
                <li></li>
                <li></li>
            </ol>
        </div>
</div>

css样式

    * {
            margin: 0px;
            padding: 0px;
            /* 移动端适配核心点
                1.不允许网页出现横向滚动条
                2.页面盛满屏幕,盒子宽度与屏幕一致 100%
                3.让盒子的内容宽高width/height包含padding与border,避免出现横向滚动条  
            */
            box-sizing: border-box;
        }
        body {
            /* 移动端默认字体一般是12px */
            font-size: 12px;
        }
        li {
            list-style: none;
        }
        img {
            vertical-align: middle;
            /* 图片居中 */
        }
        a {
            color: #000;
            /* 取消a标签默认下划线 */
            text-decoration: none;
            /* 移动端点击a链接出现蓝色背景问题解决 */
            -webkit-tap-highlight-color: transparent;
        }
        /* 清除浮动,解决margin-top塌陷 */
        .clearfix:after {
            content: "";
            display: block;
            height: 0;
            clear: both;
            visibility: hidden;
        }
        .container {
            width: 100%;
            /* 限制版心的宽度范围,在pc端也能显示移动端网页 */
            max-width: 1024px;
            min-width: 320px;
            margin: 0 auto;
        }
        .banner {
            width: 100%;
            margin-top: 44px;
            position: relative;
            overflow: hidden;
        }
        .banner img {
            width: 100%;
        }
        .banner ol {
            position: absolute;
            right: 20px;
            bottom: 5px;
        }
        .banner ol .current {
            width: 15px;
        }
        .banner ol li {
            display: inline-block;
            width: 5px;
            height: 5px;
            border-radius: 2px;
            list-style: none;
            background-color: red;
        }
        .banner ul {
            width: 500%;
            margin-left: -100%;
            overflow: hidden;
        }
        .banner ul li {
            float: left;
            width: 20%;
        }

案例分析:

  • 1.自动轮播
  • 2.开启定时器
  • 3.移动端移动,可以使用translate移动
  • 4.想要图片缓动效果,添加过渡transition效果

实现播放功能后,接着实现无缝滚动

  • 自动播放功能无缝滚动
  • 注意:我们判断条件是要等到图片滚动完毕再去判断,就是过渡完成后判断
  • 此时需要添加检测过渡完成事件transitionend
  • 判断条件:如果索引号等于3说明走到最后一张图片,此时索引号要复原为0
  • 此时图片,去掉过渡效果,然后移动
  • 如果索引号小于0,说明是倒着走,索引号改为2
  • 此时图片,去掉过渡效果,然后移动

无缝滚动实现完之后接着实现改变li小圆点的样式变换

这里介绍一个新的classList属性:它是HTML5新增的一个属性,返回元素的类名,但是ie10以上的版本才支持,该属性用于在元素中添加、移出、切换css类,有以下方法:

元素.classList.add('类名')、元素.classList.remove('类名')、元素.classList.toggle('类名')

    <style>
        .bg{
            background-color: black;
        }
    </style>
    
    <div class="one two"></div>
    <button>开关</button>
    <script>
        var div = document.querySelector("div");
        console.log(div.classList);//DOMTokenList(2) ["one", "two", value: "one two"]
        //1.添加类名 是在后面追加类名不会覆盖以前的类名
        div.classList.add('three');
        console.log(div.classList);//DOMTokenList(3) ["one", "two", "three", value: "one two three"]
        //2.删除类名
        div.classList.remove('one');
        console.log(div.classList);//DOMTokenList(2) ["two", "three", value: "two three"]
        //3.切换类
        var btn = document.querySelector("button");
        btn.onclick = function(){
            document.body.classList.toggle("bg");
        }
    </script>

了解完classList之后我们来做小圆点样式改变效果:

  • 1.小圆点跟随变化效果
  • 2.吧ol中li带有current类名选出来去掉类名current
  • 3.让当前索引号的li加上current
  • 4.注意:等着过渡结束之后再去添加current,所以要写在transitionend中

接着开始实现手指滑动轮播:

  • 1.本质就是ul跟着手指移动,简单说就是移动拖动元素
  • 2.触摸元素touchstart:获取手指初始坐标
  • 3.移动手指touchmove:计算手指的滑动距离,并且移动盒子
  • 4.手指离开touchend,根据移动距离去判断是回弹还是播放上一张下一张
  • 5.如果移动距离小于某个像素 就回弹
  • 6.如果移动距离大于某个像素就上一张或者下一张

js代码:

<script>
    //1.获取元素
    var banner = document.querySelector(".banner");
    var ul = document.querySelector(".banner ul");
    var ol = document.querySelector(".banner ol");
    //获取banner的宽度
    var w = banner.offsetWidth;
    //2.利用定时器自动轮播图片
    var index = 0;
    var timer = setInterval(function () {
        index++;
        var translatex = -index * w;
        ul.style.transition = "all .3s";
        ul.style.transform = "translateX(" + translatex + "px)";
    }, 2000);
    //等着过度完成之后,再去判断 监听过渡完成的时间transitionend
    ul.addEventListener("transitionend", function () {
        //无缝滚动
        if (index >= 3) {
            index = 0;
            //为了让图片瞬间到索引0处,要取消掉过渡效果
            ul.style.transition = "none";
            //利用最新的索引乘宽度 滚动图片
            var translatex = -index * w;
            ul.style.transform = "translateX(" + translatex + "px)";
        } else if (index < 0) { //同理
            index = 2;
            ul.style.transition = "none";
            var translatex = -index * w;
            ul.style.transform = "translateX(" + translatex + "px)";
        }
        //3.小圆点跟随变化
        //吧ol中的li带有current类名选出来去掉类名 remove
        ol.querySelector('.current').classList.remove('current')
        //让当前索引号的小li加上current 类名
        ol.children[index].classList.add('current');
    });

    //4.手指滑动轮播图
    //触摸元素touchstart:获取手指初始坐标
    var startX = 0;
    var moveX = 0; //因为后面需要使用移动距离,因此定义一个全局变量
    var flag = false;
    ul.addEventListener("touchstart", function (e) {
        //当触摸到ul时候 清除定时器
        clearInterval(timer);
        startX = e.targetTouches[0].pageX;
    });
    //移动手指 touchmove:计算手指的滑动距离 ,并且移动盒子
    ul.addEventListener("touchmove", function (e) {
        //计算移动距离
        moveX = e.targetTouches[0].pageX - startX;
        //移动盒子:盒子原来的位置+手指移动的距离
        var translateX = -index * w + moveX;
        //手指拖动的时候,不需要动画效果所以要取消过渡效果
        ul.style.transition = "none";
        ul.style.transform = "translateX(" + translateX + "px)";
        flag = true;//如果用户手指移动了我们才判断否则不去判断效果
        e.preventDefault();//阻止滚动屏幕的行为
    });
    //手指离开,根据移动距离去判断是回弹还是播放上一张下一张
    ul.addEventListener("touchend", function (e) {
        if (flag) {
            //如果移动距离大于50像素 我们就播放上一张或者下一张
            if (Math.abs(moveX) > 50) { //为了防止负数需要取绝对值
                //如果是右滑 播放上一张moveX是正数
                //如果是左滑 播放下一张moveX是负数
                moveX > 0 ? index-- : index++;

                var translateX = -index * w;
                ul.style.transition = "all .3s";
                ul.style.transform = "translateX(" + translateX + "px)";
            } else {
                //如果小于50px就回弹
                var translateX = -index * w;
                ul.style.transition = "all .1s";
                ul.style.transform = "translateX(" + translateX + "px)";
            }
        }
        //手指离开就清楚定时器
        clearInterval(timer);
        timer = setInterval(function () {
            index++;
            var translatex = -index * w;
            ul.style.transition = "all .3s";
            ul.style.transform = "translateX(" + translatex + "px)";
        }, 2000);
    });
</script>

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.触屏事件
    • 1.1触屏事件概述
      • 1.2触摸事件对象(TochEvent)
        • 1.3移动端拖动元素
        • 2.移动轮播案例
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档