面向对象の轮播图(四)-废

学废了家人们

建议作为艺术品鉴赏吧,等有能力在完全搞定!!!
index.html

<!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>
        .div1{
      
      
            width: 900px;
            height: 300px;
        }
    </style>
</head>
<body>
    <button>按钮</button>
    <div class="div1"></div>
    <script type="module">
        import Carousel from "./js/Carousel.js";

        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:"寻迹山川湖海,邂逅云南的冬与夏"},
        ]


        var list=[
            {
      
      id:1006,img:"./img/a2.jpg",date:"2/Nov.2021",info:"食欲拯救计划|阿一古~是贼拉好吃的延吉啊!"},
            {
      
      id:1007,img:"./img/b2.jpg",date:"1/Nov.2021",info:"徽州古村落赏秋自驾9日攻略!给这个秋天一个说走就走的理由!"},
            {
      
      id:1008,img:"./img/c2.jpg",date:"31/Oct.2021",info:"致,荆棘鸟与淘金先驱者——三赴西澳自驾笔记"},
            {
      
      id:1009,img:"./img/d2.jpg",date:"30/Oct.2021",info:"我是你的俘虏【跟新疆私奔】"},
            {
      
      id:1010,img:"./img/e2.jpg",date:"29/Oct.2021",info:"遇见阳朔的光与影,晨与昏,山与水"},
            {
      
      id:1011,date:"12/Jul.2021",info:"No Fear in My Heart. 10天4700公里,自由散漫南疆奇遇记。",img:"./img/a1.jpeg"},
            {
      
      id:1012,date:"11/Jul.2021",info:"128座乐园!284座过山车!我的全球乐园打卡计划持续更新ing",img:"./img/b1.jpg"},
            {
      
      id:1013,date:"10/Jul.2021",info:"带着父母旅行的第四年,疫情下的Flag小旗在广州飘~谢谢你们陪着我,会勇敢坚定的走自己的路",img:"./img/c1.jpg"},
            {
      
      id:1014,date:"09/Jul.2021",info:"念念闽夏|日子娓娓,一如夏季绵长",img:"./img/d1.jpg"},
            {
      
      id:1015,date:"08/Jul.2021",info:"30天自驾16座城市,从南到北,一万公里重新认识你。(海南-内蒙古-海南)",img:"./img/e1.jpg"},
        ]

        // var carousel=new Carousel();
        // carousel.setData(arr);//设置数据,没有数据之前,这个轮播图没有图片和小圆点
        // carousel.appendTo("body");//没有放在页面上之前 offsetWidth  offsetLeft一概不能获取到


        // animation();

        // function animation(){
      
      
        //     requestAnimationFrame(animation);
        //     carousel.update();
        // }



        // var bn=document.querySelector("button");
        // bn.addEventListener("click",clickHandler);

        // function clickHandler(e){
      
      
        //     carousel.setData(list);
        // }




        var c1=new Carousel(arr);
        c1.appendTo(".div1");
        var c2=new Carousel(list);
        c2.appendTo("body");

        animation();

        function animation(){
      
      
            requestAnimationFrame(animation);
            Carousel.update();
        }
    </script>
</body>
</html>

Utils.js

export default class Utils{
    
    
    static setCSS(css){
    
    
       if(document.styleSheets.length===0 || !Array.from(document.styleSheets).some(item=>item.ownerNode.id==="defined")){
    
    
         var style=document.createElement("style");
         style.innerHTML=css;
         style.id="defined"
         document.head.appendChild(style);
         return;
       }
       var styleSheet=Array.from(document.styleSheets).find(item=>item.ownerNode.id==="defined");
       var arr=css.split(/(?<=\})/).map(item=>item.trim());
       arr.forEach(item=>{
    
    
         styleSheet.insertRule(item,styleSheet.cssRules.length);
       })
    }
    static createElement(type,className,parent){
    
    
       if(typeof parent==="string") parent=document.querySelector(parent);
       var elem=document.createElement(type);
       if(className) elem.className=className;
       if(parent instanceof HTMLElement) parent.appendChild(elem);
       return elem;
    }
}

component.js

export default class Component{
    
    
    elem;
    constructor(type){
    
    
        this.elem=document.createElement(type);
    }
    appendTo(parent){
    
    
        if(typeof parent==="string") parent=document.querySelector(parent);
        parent.appendChild(this.elem);
        return parent;
    }
    insertTo(parent,nextElement){
    
    
        if(typeof parent==="string") parent=document.querySelector(parent);
        if(typeof nextElement==="string") nextElement=document.querySelector(nextElement);
        if(parent instanceof HTMLElement && nextElement instanceof HTMLElement)
        parent.insertBefore(this.elem,nextElement);
    }
}

Carousel.js

import Component from "./Component.js";
import Utils from "./Utils.js";
export default class Carousel extends Component{
    
    
    static MAX_TIME=200;
    LEFT=Symbol();
    RIGHT=Symbol();
    imgCon;
    left;
    right;
    dot;
    list;
    prev;
    direction;
    pos=0;
    speed=50;
    x=0;
    autoBool=false;
    time;
    blockList={
    
    };
    bool=false;
    static carouselList=new Set();
    static cssBool=false;
    constructor(_list){
    
    
        super("div");
        this.direction=this.LEFT;
        this.time=Carousel.MAX_TIME;
        this.elem.className="carousel";
        this.imgCon=Utils.createElement("div","img-con",this.elem);
        this.dot=Utils.createElement("ul","dot",this.elem);
        this.left=Utils.createElement("canvas","left",this.elem);
        this.right=Utils.createElement("canvas","right",this.elem);
        this.left.width=this.right.width=30;
        this.left.height=this.right.height=60;
        this.drawBn(this.left,this.LEFT);
        this.drawBn(this.right,this.RIGHT);
        if(_list) this.setData(_list);
        Carousel.carouselList.add(this);
        this.elem.addEventListener("click",e=>this.clickHandler(e));
        this.elem.addEventListener("mouseenter",e=>this.mouseHandler(e))
        this.elem.addEventListener("mouseleave",e=>this.mouseHandler(e))
        if(!Carousel.cssBool) Carousel.setStyle();
    }
    mouseHandler(e){
    
    
        this.autoBool=e.type==="mouseleave";
        this.time=Carousel.MAX_TIME;//设置时间恢复最大间隔时间
    }
    appendTo(parent){
    
    
        parent=super.appendTo(parent);
        if(parent.nodeName==="BODY") this.elem.style.height="33.3vw";
        else this.elem.style.height="100%";
    }
    setData(_list){
    
    
        if(!Array.isArray(_list))return;
        // 清除上一次设置轮播图里面的内容
        this.imgCon.innerHTML="";
        this.list=null;
        this.blockList=null;
        this.blockList={
    
    };
        this.list=_list;
        this.dot.innerHTML=this.list.reduce(v=>v+"<li></li>","");
        this.imgCon.appendChild(this.getImgBlock(this.list[this.pos]))
        this.changePrev();
    }

    getImgBlock(data){
    
    
        // 在存储对象中查找有没有当前数据id作为key存储内容,如果有直接返回
        if(this.blockList[data.id]) return this.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存储在存储对象中
        this.blockList[data.id]=div;
        // 返回创建好的div
        return div;
    }
    drawBn(elem,direction){
    
    
        var ctx = elem.getContext("2d");
            ctx.fillStyle = "white"
            ctx.beginPath();
            ctx.moveTo(4, 31);
            ctx.lineTo(22, 9);
            ctx.lineTo(21, 17);
            ctx.lineTo(12, 30);
            ctx.lineTo(21, 43);
            ctx.lineTo(22, 51);
            ctx.closePath();
            ctx.fill();
        if(direction===this.RIGHT) elem.style.transform = "scale(-1,1) translate(0px, -50%)";
    }
    clickHandler(e){
    
    
        if(this.bool) return;
            // 如果className不是left或者right,并且被点击的元素也不是LI 跳出
            if(!/left|right/.test(e.target.className) && e.target.nodeName!=="LI") return;
            if(e.target.className==="left"){
    
    
                // 如果点击按钮是左按钮
                this.direction=this.RIGHT;
                // pos递减,并且如果pos是最前面时,让pos为最后一个
                if(--this.pos<0)this.pos=this.list.length-1;
            }else if(e.target.className==="right"){
    
    
                // 如果点击按钮是右按钮
                this.direction=this.LEFT;
                // pos递加,如果pos是最后一个,让pos为第一个
                if(++this.pos>this.list.length-1) this.pos=0;
            }else{
    
    
                // 根据当前点击li是父容器的所有子元素中的第几个获取到点击的索引
                var index=Array.from(e.target.parentElement.children).indexOf(e.target);
            //   如果点击的索引就是当前的显示的索引,跳出
                if(this.pos===index) return;
                // 如果点击的索引大于当前的索引,设置方向为LEFT,否则设置为RIGHT
                this.direction= index>this.pos ? this.LEFT : this.RIGHT;
                // 并且将点击的索引重新赋值给当前索引
                this.pos=index;
            }
            this.changePrev();
            this.createNextImg();
    }
    changePrev(){
    
    
        if(this.prev){
    
    
            this.prev.style.backgroundColor="transparent"
        }
        this.prev=this.imgCon.nextElementSibling.children[this.pos];
        this.prev.style.backgroundColor="red";
    }
    createNextImg(){
    
    
        if(this.direction===this.LEFT){
    
    
            // 将当前点击的要变化的索引对应div获取插入在容器的尾部
            this.imgCon.appendChild(this.getImgBlock(this.list[this.pos]));
            this.x=0;
        }else{
    
    
            // 将需要变化索引的图片插入在轮播容器的最前面
            this.imgCon.insertBefore(this.getImgBlock(this.list[this.pos]),this.imgCon.firstElementChild);
            this.x=-this.imgCon.offsetWidth/2;
        }
        // 并且重新设置轮播容器位置
        this.imgCon.style.left=this.x+"px";
        this.bool=true;
    }

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

     autoPlay(){
    
    
        // 如果自动轮播没有开启就跳出
        // 如果自动轮播开启,但是time递减后大于0,则跳出
        if(!this.autoBool || --this.time>0)return;
        // 设置当前间隔时间为最大
        this.time=Carousel.MAX_TIME;
        // 向right按钮抛发点击事件,触发轮播
        var evt=new MouseEvent("click",{
    
    bubbles:true});
        this.imgCon.parentElement.lastElementChild.dispatchEvent(evt);
    }
    static setStyle(){
    
    
        Carousel.cssBool=true;
        Utils.setCSS(` body{
            margin: 0;
            padding: 0;
        }
        .carousel{
            width: 100%;
            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;
        }`)
    }
   
}

猜你喜欢

转载自blog.csdn.net/m0_46672781/article/details/126073788