javaScript详解数据驱动显示之轮播图案例——三-----手撕轮播图

Posted 勇敢*牛牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javaScript详解数据驱动显示之轮播图案例——三-----手撕轮播图相关的知识,希望对你有一定的参考价值。

javascript详解数据驱动显示之轮播图案例三

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body
            margin: 0;
            padding: 0;
        
        .carousel
            width: 100%;
            height: 33.3vw;
            position: relative;
            left: 0;
            top: 0;
            font-size: 0;
            min-width: 1000px;
            overflow: hidden;
        
        .carousel>.img-con
            width: 200%;
            height: 100%;
            position: absolute;
            left: 0;
        
        .carousel .img-block
            width: 50%;
            height: 100%;
            position: relative;
            float: left;
            
        
        .carousel .img-block>img
            width: 100%;
            height: 100%;
            position: absolute;
            left: 0;
            top: 0;
        
        .carousel .img-block>div
            position: absolute;
            left:10vw;
            top: 2vw;
            font-size: 20px;
            color: white;
        
        .carousel .img-block>div>span>i
            font-style:normal;
            font-size: 28px;
        
        .carousel .img-block>div>h1
            font-size: 20px;
        
        .clear::after
        
            content: "";
            display: block;
            visibility: hidden;
            height: 0;
            overflow: hidden;
            clear: both;
        

        ul
            list-style: none;
            position: absolute;
            bottom: 3vw;
            left: 50%;
            transform: translate(-50%,0);
        
        ul li
            width: 1.6vw;
            height: 1.6vw;
            border:2px solid red;
            margin-left: 1.3vw;
            float: left;
            border-radius: 1.6vw;
            
        
        .left,.right
            position: absolute;
            top: 50%;
            transform: translate(0,-50%);
        
        .left
            left: 3vw;
        

        .right
            right: 3vw;
        
    </style>
</head>
<body>
    <script>
        const LEFT=Symbol("LEFT"),RIGHT=Symbol("RIGHT"),MAX_TIME=200;
        var arr=[
            id:1001,img:"./img/a.jpg",date:"28/Jul/2022",info:"与父母的47天自驾游|向疆而行2万里,我们依旧是过客",
            id:1002,img:"./img/b.jpg",date:"27/Jul/2022",info:"自驾川西小环线,在千碉之国遇见梨花如雪的季节",
            id:1003,img:"./img/c.jpg",date:"26/Jul/2022",info:"被误解的沙县,原来有这么多美食只有在当地才能吃到!",
            id:1004,img:"./img/d.jpg",date:"25/Jul/2022",info:"周末出逃计划 | 打卡美丽中国",
            id:1005,img:"./img/e.jpg",date:"24/Jul/2022",info:"寻迹山川湖海,邂逅云南的冬与夏",
        ],
        pos=0,
        x=0,
        bool=false,
        speed=50,
        direction=LEFT,
        autoBool=true,
        time=MAX_TIME,
        blockList=;
        var imgCon,prev;
        init();
        // 初始化
        function init()
            // 创建一个最外层轮播图的div
            var carousel=document.createElement("div");
            carousel.className="carousel";
            // 设置里面的html内容,根据数据的数量生成多个li
            carousel.innerHTML=`
                <div class='img-con'></div>
                <ul>$arr.reduce(v=>v+"<li></li>","")</ul>
                <img src='./img/left.png' class='left'>
                <img src='./img/right.png' class='right'>    
            `
            // 获取这个标签中img-con这个容器
            imgCon=carousel.querySelector(".img-con");
            // 获取第0张图片的对应的div,放在这个容器中
            imgCon.appendChild(getImgBlock(arr[0]));
            // 给最外层容器做事件委托点击
            carousel.addEventListener("click",clickHandler);
            carousel.addEventListener("mouseenter",mouseHandler)
            carousel.addEventListener("mouseleave",mouseHandler)
            changePrev();
            document.body.appendChild(carousel);
            animation();
        

        function mouseHandler(e)
            // 当鼠标离开时,自动轮播
            autoBool=e.type==="mouseleave";
            time=MAX_TIME;//设置时间恢复最大间隔时间
        

        function getImgBlock(data)
            // 在存储对象中查找有没有当前数据id作为key存储内容,如果有直接返回
            if(blockList[data.id]) return blockList[data.id];
            // 传递div
            var div=document.createElement("div");
            div.className="img-block"
            // 根据数据设置这个div中的内容
            div.innerHTML=`
                <img src="$data.img">
                <div>
                    <span><i>$data.date.split("/").shift()</i>$data.date.match(/\\/.*/)[0].replace(/\\/(?=\\d+)/,".")</span>
                    <h1>$data.info</h1>
                </div>
            `
            // 将创建好的div用id作为key存储在存储对象中
            blockList[data.id]=div;
            // 返回创建好的div
            return div;
        

        function clickHandler(e)
            // 如果动画正在播放,不能点击
            if(bool) return;
            // 如果className不是left或者right,并且被点击的元素也不是LI 跳出
            if(!/left|right/.test(e.target.className) && e.target.nodeName!=="LI") return;
            if(e.target.className==="left")
                // 如果点击按钮是左按钮
                direction=RIGHT;
                // pos递减,并且如果pos是最前面时,让pos为最后一个
                if(--pos<0)pos=arr.length-1;
            else if(e.target.className==="right")
                // 如果点击按钮是右按钮
                direction=LEFT;
                // pos递加,如果pos是最后一个,让pos为第一个
                if(++pos>arr.length-1) pos=0;
            else
                // 根据当前点击li是父容器的所有子元素中的第几个获取到点击的索引
                var index=Array.from(e.target.parentElement.children).indexOf(e.target);
            //   如果点击的索引就是当前的显示的索引,跳出
                if(pos===index) return;
                // 如果点击的索引大于当前的索引,设置方向为LEFT,否则设置为RIGHT
                direction= index>pos ? LEFT : RIGHT;
                // 并且将点击的索引重新赋值给当前索引
                pos=index;
            
            changePrev();
            createNextImg();
        

        function changePrev()
            if(prev)
                prev.style.backgroundColor="transparent"
            
            prev=imgCon.nextElementSibling.children[pos];
            prev.style.backgroundColor="red";
        

        function createNextImg()
            if(direction===LEFT)
                // 将当前点击的要变化的索引对应div获取插入在容器的尾部
                imgCon.appendChild(getImgBlock(arr[pos]));
                x=0;
            else
                // 将需要变化索引的图片插入在轮播容器的最前面
                imgCon.insertBefore(getImgBlock(arr[pos]),imgCon.firstElementChild);
                x=-imgCon.offsetWidth/2;
            
            // 并且重新设置轮播容器位置
            imgCon.style.left=x+"px";
            bool=true;
        

        function animation()
            requestAnimationFrame(animation);
            imgMove();
            autoPlay();
        

        function imgMove()
            // 如果bool是非,就不进入动画,这个bool控制是否进入动画
            if(!bool) return;
            if(direction===LEFT)
                // 如果方向向左走,让x不断递减
                x-=speed;
                // 如果容器已经向左运行一半时
                if(x<=-imgCon.offsetWidth/2)
                    // 停止动画
                    bool=false;
                    // 删除第一个图片,第二张掉在前面去,
                    imgCon.firstElementChild.remove();
                    // 这时候将整体重新挪回到0的位置
                    x=0;
                
            else
                // 如果方向向右走,让x不断递加
                x+=speed;
                if(x>=0)
                    // 当x大于等于0,让动画停止
                    bool=false;
                    // 并且删除最后一张图片
                    imgCon.lastElementChild.remove();
                     // 这时候将整体重新挪回到0的位置
                    x=0;
                
            
            // 设置改变图片容器的位置
            imgCon.style.left=x+"px";
        

        function autoPlay()
            // 如果自动轮播没有开启就跳出
            // 如果自动轮播开启,但是time递减后大于0,则跳出
            if(!autoBool || --time>0)return;
            // 设置当前间隔时间为最大
            time=MAX_TIME;
            // 向right按钮抛发点击事件,触发轮播
            var evt=new MouseEvent("click",bubbles:true);
            imgCon.parentElement.lastElementChild.dispatchEvent(evt);
        
     
      
    </script>
</body>
</html>

以上是关于javaScript详解数据驱动显示之轮播图案例——三-----手撕轮播图的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序之轮播图

web常见效果之轮播图

CycleRotationView:自定义控件之轮播图

JS之轮播图自动切换效果

小程序之轮播图(2020.4.13更新)

Android自己定义控件之轮播图控件