移动端事件(二)—— 移动端滑屏切换的幻灯片

233 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

经过昨天对移动端基础的了解,今天就来用原生JS实现一下我们的幻灯片。

因为是用原生实现,所以本文篇幅较长,只需理解思路即可,代码部分可以粗略看看。

毕竟我们有better-scroll这样封装好的框架能更快速实现效果。b( ̄▽ ̄)d 

首先根据我们昨天的滑屏操作,先将幻灯片的滑屏效果做出来。这里大家将照片地址更换成自己的就能得到效果。

案例要在客户端才有效果哦,如果在PC端,网页中右键点审查,控制器旁边有个手机图标,点击下图这个也能有效果。

img

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        html {
            font-size: 10vw;
        }
        body {
            margin: 0;
        }
        ul {
            margin: 0;
            padding: 0;
            list-style: none;
        }
        #wrap {
            position: relative;
            width: 100vw;
            overflow: hidden;
        }
        #list {
            float: left;
            display: flex;
            display: -webkit-box;
        }
        #list li {
            flex: none;
            width: 100vw;
        }
        #list img {
            width: 100%;
            display: block;
        }
        .nav {
            position: absolute;
            left: 0;
            bottom: .2rem;
            width: 100%;
            text-align: center;
            vertical-align: top;
        }
        .nav a {
            display: inline-block;
            width: .3rem;
            height: .3rem;
            background: #fff;
            margin: 0 .1rem;
            border-radius: .15rem;
            transition: .3s;
        }
        .nav .active {
            width: .6rem;  
            color: #fff;  
        }
    </style>
</head>
<body>  
<div id="wrap">
    <ul id="list">
        <li><img src="img/banner01.png" /></li>
        <li><img src="img/banner02.png" /></li>
        <li><img src="img/banner03.png" /></li>
        <li><img src="img/banner04.png" /></li>
    </ul>
    <nav class="nav">
        <a class="active"></a><a></a><a></a><a></a>
    </nav>
</div>  
<script>
 // 幻灯片效果   
{
    let wrap = document.querySelector("#wrap");
    let list = document.querySelector("#list");
    let navs = document.querySelectorAll(".nav a");
    let translateX = 0; //元素的移动位置
    let startPoint = {}; //摁下时手指坐标
    let disPoint = {};//手指移动距离
    let startX = 0;//摁下时元素坐标

    wrap.addEventListener("touchstart",({changedTouches})=>{
        startPoint = {
            x: changedTouches[0].pageX,
            y: changedTouches[0].pageY
        };
        startX = translateX;
    });
    wrap.addEventListener("touchmove",(e)=>{
        let touch = e.changedTouches[0];
        let nowPoint = {
            x: touch.pageX,
            y: touch.pageY
        };
        disPoint = {
            x: nowPoint.x - startPoint.x,
            y: nowPoint.y - startPoint.y
        };
        translateX = disPoint.x + startX;
        list.style.transform = `translateX(${translateX}px)`;
    });
}   
</script>
</body>
</html>

滑屏效果做出来以后,我们给它添加动画,接下来为了大家方便看,就只写JavaScript的代码。红色的为添加的新代码。

<script>
 // 幻灯片效果   
{
    let wrap = document.querySelector("#wrap");
    let list = document.querySelector("#list");
    let navs = document.querySelectorAll(".nav a");
    let translateX = 0; //元素的移动位置
    let startPoint = {}; //摁下时手指坐标
    let startX = 0;//摁下时元素坐标
    let disPoint = {};//手指移动距离
    let now = 0; // 记录当前在第几张
    const Range = .3* wrap.clientWidth; // 移动超过屏幕 30% 时,抬起切换到下一张

    wrap.addEventListener("touchstart",({changedTouches})=>{
        list.style.transition = "none";
        startPoint = {
            x: changedTouches[0].pageX,
            y: changedTouches[0].pageY
        };
        startX = translateX;
        
    });
    wrap.addEventListener("touchmove",(e)=>{
        let touch = e.changedTouches[0];
        let nowPoint = {
            x: touch.pageX,
            y: touch.pageY
        };
        disPoint = {
            x: nowPoint.x - startPoint.x,
            y: nowPoint.y - startPoint.y
        };
        translateX = disPoint.x + startX;
        list.style.transform = `translateX(${translateX}px)`;
    });
    wrap.addEventListener("touchend",()=>{
        if(Math.abs(disPoint.x)>Range){ //切换到下一张
            //console.log(disPoint.x/Math.abs(disPoint.x));
            now -= disPoint.x/Math.abs(disPoint.x);
            // 求当前要看第几张
        }
        translateX = -now*wrap.clientWidth;
        list.style.transition = ".3s";
        list.style.transform = `translateX(${translateX}px)`;
        //console.log(now);
    });
}   
</script>

这一步我们将每次手指离开屏幕后进行判断,判断手指移动的距离是否超过30%,抬起则切换到下一张。我们在每次切换时添加了0.3s的延迟动画。因为这延迟动画在手指触屏时就会生效,所以我们在touchstart的时候将它清除。

我们实现上面效果后,可以发现会有划出去的风险,接下来我们要实现无缝滚动,由于篇幅较长,留到下一篇继续讲。