美文网首页
ES6轮播图插件自制

ES6轮播图插件自制

作者: beensolong | 来源:发表于2020-09-18 20:07 被阅读0次

插件描述

  • 一行代码在你想要的位置生成一个轮播图

插件使用说明

  • import插件
  • 在html页面中书写一个容器(即调用插件时的形参1parent),给这个容器书写css样式,包括宽度和位置等
  • 使用语句Carousel.createCarousel(parent,arr)生成轮播图.其中形参1是用来承载轮播图的容器,可以输入选择符字符串也可以输入节点;形参2是轮播图图片的src数组。
<script type="module">
    import Carousel from "url"
    Carousel.createCarousel(parent,arr)
</script>

插件编写思路

1.采用静态函数编写接口static createCarousel(parent,arr)

2.分析轮播图组成元素,需要一个轮播图容器(carousel_wrapper),一个可以装下两张图片的图片容器(img_wrapper),两个btn,跟图片个数相等的选项卡圆点;

3.将功能拆解:

  • 图片预加载
  • 创建轮播图元素
  • 左右按钮的点击事件
  • 添加需要参与下次轮播的图片进入img_wrapper
  • 选项卡圆点的mouseover事件
  • 更改选项卡圆点的样式
  • 自动轮播

插件编写心得

  • 函数式编程不仅仅是把代码写在一个个函数中被包裹,得注意每个函数尽可能单独完成一个唯一的功能,这样,元素的事件中就可以灵活的调用函数。
  • 标志变量的使用非常重要。可以使用其作为开关,在程序中设置手动切换轮播图的开关,设置自动轮播的暂停与继续;也可以使用其作为逻辑分叉的判断条件

插件实现细节(部分)

if(typeof parent === "string") Carousel.parent=document.querySelector(parent);

  • 参1可输入元素节点或元素节点的选择符字符串

Carousel.loadImg(Carousel.arr,Carousel.imgLoadedHandler)

  • 将形参2传入的图片src数组进行图片的预加载

Carousel.WIDTH = parseFloat(Carousel.list[0].width)

  • 将第一张图片的宽高设置为carousel_wrapper的宽高

Carousel.createNextImg()

  • 动态向img_wrapper中添加图片实现无缝轮播

height:${Carousel.HEIGHT}px

  • 将形参1元素的高度动态设置为图片高度,解决高度塌陷问题

插件将carousel_wrapper设置了居中,即传入的形参1元素的水平中间,使得小像素显示屏也能显示大像素图片

注意事项

  • \color{orange}{选项卡圆点和左右按钮,插件都自带,插件会给形参1元素动态设置高度为形参2src数组第一个src代表的图片的高度}
  • 形参1parent代表的元素不需要任何的innerHTML,如果写了也会被插件清空
  • 为了增强插件的稳定性,插件给形参1(parent)设置部分属性,如下
    Object.assign(Carousel.parent.style,{
              position:"relative",
              height:`${Carousel.HEIGHT}px`,
              zIndex:99999,
              overflowX:"hidden"
          });
    
  • 左右按钮和选项卡圆点是固定尺寸的,适合较大的轮播图,如果图片较小可以手动修改其尺寸

插件源代码

export default class Carousel{
    static prev;
    static pos = 0;
    static dots=[];
    static time = 300;
    static auto_play = true;
    static isMoving = false;
    static direction;
    static speed = 20;
    static parent;
    static list=[];
    static carousel_wrapper;
    static WIDTH ;
    static HEIGHT;
    static go_left_btn;
    static go_right_btn;
    static img_wrapper;
    static btn_list;
    static screen_width;
    static screen_height;
    static arr;
    
    //接口,导出插件生成的轮播图,用参数parent接受
    static createCarousel(parent,arr){
        Carousel.arr = arr;
        Carousel.screen_width = window.innerWidth;
        Carousel.screen_height = window.innerHeight;
        Carousel.parent = parent;
        if(typeof parent === "string") Carousel.parent=document.querySelector(parent);
        Carousel.parent.innerHTML=""
        Carousel.loadImg(Carousel.arr,Carousel.imgLoadedHandler);
    }
    //图片预加载
    static imgLoadedHandler(list){
        for(let i = 0;i < list.length;i++){
            Carousel.list.push(list[i]);
        }
        Carousel.WIDTH = parseFloat(Carousel.list[0].width);
        Carousel.HEIGHT = parseFloat(Carousel.list[0].height);
        Object.assign(Carousel.parent.style,{
            position:"relative",
            height:`${Carousel.HEIGHT}px`,
            zIndex:99999,
            overflowX:"hidden"
        });
        Carousel.carousel_wrapper = Carousel.createCarouselWrapper();
        Carousel.createImgWrapper(Carousel.carousel_wrapper);
        Carousel.carousel_wrapper.addEventListener("mouseover",Carousel.mouseHandler);
        Carousel.carousel_wrapper.addEventListener("mouseout",Carousel.mouseHandler);
        Carousel.createBtn(Carousel.carousel_wrapper);
        Carousel.createDots(Carousel.carousel_wrapper);
        Carousel.go_left_btn.addEventListener("click",Carousel.clickHandler);
        Carousel.go_right_btn.addEventListener("click",Carousel.clickHandler);
        Carousel.autoPlay();
        Carousel.img_wrapper.appendChild(Carousel.list[0]);
        Carousel.parent.appendChild(Carousel.carousel_wrapper);
    }
    //创建轮播图外围容器
    static createCarouselWrapper(){
        let carousel_wrapper = Carousel.ce("div",{
            width: `${Carousel.WIDTH}px`,
            height:`${Carousel.HEIGHT}px`,
            position:"absolute",
            left:"50%",
            marginLeft:`${-Carousel.WIDTH*0.5}px`,
            overflowX:"hidden"
        });
        return carousel_wrapper;
    }
    //创建一个可以容纳两张图片的盒子
    static createImgWrapper(parent,arr){
        Carousel.arr = arr;
        Carousel.img_wrapper = Carousel.ce("div",{
            width: `${Carousel.WIDTH*2}px`,
            height:`${Carousel.HEIGHT}px`,
            position:"absolute",
            left:0
        },parent)
    }
    //创建两个按钮
    static createBtn(parent){
        Carousel.go_left_btn = new Image();
        Carousel.go_left_btn.src="https://p2.lefile.cn/product/adminweb/2018/11/11/2a7f8349-14f0-42e1-afe8-7ae8afd54e1e.png";
        Carousel.go_right_btn = new Image();
        Carousel.go_right_btn.src="https://p2.lefile.cn/product/adminweb/2018/11/11/cae7b801-0fe6-4691-ba99-239ba9d11576.png";
        Object.assign(Carousel.go_left_btn.style,{
            position:"absolute",
            left:`${Carousel.WIDTH*0.5-Carousel.screen_width*0.5}px`,
            marginLeft:`100px`,
            top:`${Carousel.HEIGHT*0.5}px`,
            marginTop:`${-Carousel.go_right_btn.height*0.5}px`
        })
        Object.assign(Carousel.go_right_btn.style,{
            position:"absolute",
            left:`${Carousel.WIDTH*0.5-Carousel.screen_width*0.5+Carousel.screen_width}px`,
            marginLeft:`-100px`,
            top:`${Carousel.HEIGHT*0.5}px`,
            marginTop:`${-Carousel.go_right_btn.height*0.5}px`
        })
        parent.appendChild(Carousel.go_left_btn)
        parent.appendChild(Carousel.go_right_btn)
    }
    //创建圆点选项卡
    static createDots(parent){
        Carousel.dots = Carousel.ce("div",{
            zIndex:66,
            background:"red",
            height:"30px",
            width:"100%",
            position:"absolute",
            textAlign:"center",
            bottom:"40px"
        },parent);
        Carousel.list.forEach((item,index)=>{
                let span = Carousel.ce("span",{
                    display:"inline-block",
                    width:"30px",
                    height:"30px",
                    borderRadius:"50%",
                    background:"white",
                    marginRight:"5px"
                },Carousel.dots)
                span.addEventListener("mouseover",Carousel.dotMouseoverHandler);
                span.span_index =index;
        })
        Carousel.prev = Carousel.dots.firstElementChild;
        Carousel.prev.style.background = "blue";
    }
    //两个按钮的点击事件
    static clickHandler(e){
        if(Carousel.isMoving)return;
        if(e.target === Carousel.go_right_btn)
            {
                Carousel.direction = "left";
                Carousel.pos++;
                if(Carousel.pos===Carousel.list.length)Carousel.pos=0;
            }
        else if(e.target === Carousel.go_left_btn){
            Carousel.direction = "right";
            Carousel.pos--;
            if(Carousel.pos===-1)Carousel.pos=Carousel.list.length-1;
        }
        Carousel.createNextImg();
        Carousel.animation();
        Carousel.changeDot();
    }
    //从存储图片元素的数组之中调出轮播需要的一张图片,并将img_wrapper位置初始化
    static createNextImg(){
        if(Carousel.direction === "left"){
            Carousel.img_wrapper.appendChild(Carousel.list[Carousel.pos]);
        }else if(Carousel.direction === "right"){
            Carousel.img_wrapper.insertBefore(Carousel.list[Carousel.pos],Carousel.img_wrapper.firstChild);
            Carousel.img_wrapper.style.left=`${-Carousel.WIDTH}px`;
        }
    }
    //图片移动动画
    static animation(){
        Carousel.isMoving = true;
        if(Carousel.direction === "right"){
            Carousel.img_wrapper.style.left = parseFloat(Carousel.img_wrapper.style.left)+Carousel.speed + "px";
            if(parseFloat(Carousel.img_wrapper.style.left)<=0) 
            {
            window.requestAnimationFrame(Carousel.animation);
            }
            else{
                window.cancelAnimationFrame(Carousel.animation)
                Carousel.img_wrapper.lastChild.remove();
                Carousel.img_wrapper.style.left = 0;
                Carousel.dot_index--;
                Carousel.isMoving = false;
                return;
            }
        }
        else if(Carousel.direction === "left"){
            Carousel.img_wrapper.style.left = parseFloat(Carousel.img_wrapper.style.left)-Carousel.speed + "px";
            if(parseFloat(Carousel.img_wrapper.style.left)>=-(Carousel.WIDTH)) 
            {
            window.requestAnimationFrame(Carousel.animation);
            }
            else{
                window.cancelAnimationFrame(Carousel.animation)
                Carousel.img_wrapper.firstChild.remove();
                Carousel.dot_index++;
                Carousel.img_wrapper.style.left = 0;
                Carousel.isMoving = false;
                return;
            }
        }
    }
    //自动轮播
    static autoPlay(){
        if(Carousel.auto_play){
            Carousel.time--;
        if(Carousel.time<=0){
                Carousel.time=300;
                let evt = new Event("click");
                Carousel.go_right_btn.dispatchEvent(evt);
            }
        }
        window.requestAnimationFrame(Carousel.autoPlay)
    };
    //实现鼠标移入轮播图区域停止自动轮播,移出继续自动轮播
    static mouseHandler(e){
        if(e.type==="mouseover"){
            Carousel.time=300;
            Carousel.auto_play = false;
        }
        else if(e.type==="mouseout"){
            Carousel.auto_play = true;
        }
    }
    //选项卡中圆点的mouseover
    static dotMouseoverHandler(e){
        if(Carousel.isMoving)return;
        if(e.target.constructor !== HTMLSpanElement)return;
        if(Carousel.pos<e.target.span_index){ 
            Carousel.direction = "left";
        }
        else if(Carousel.pos>e.target.span_index)
        {
            Carousel.direction = "right";
        }
        else return;
        Carousel.pos = e.target.span_index;
        Carousel.changeDot();
        Carousel.createNextImg();
        Carousel.animation(); 
    }
    //实现选项卡变化
    static changeDot(){
        if(Carousel.prev)Carousel.prev.style.background = "white";
        Carousel.prev = Carousel.dots.children[Carousel.pos];
        Carousel.prev.style.background = "blue";
    }
    //创建元素
    static ce(type,style,parent){
        let elem=document.createElement(type);
        if(style){
            Object.assign(elem.style,style);
        }
        if(parent){
            if(typeof parent==="string")parent=document.querySelector(parent);
            parent.appendChild(elem);
        }
        return elem;
    }
    //图片预加载
    static loadImg(arr,callBack){
        let img=new Image();
        img.src=arr.shift();
        img.arr=arr;
        img.list=[];
        img.callBack=callBack;
        img.addEventListener("load",this.loadHandler);
    }
    static loadHandler(e){
        let img=e.currentTarget;
        img.list.push(img.cloneNode(false));
        if(img.arr.length===0){
            img.callBack(img.list);
            return;
        }
        img.src=img.arr.shift();
    }
}

   

相关文章

  • ES6轮播图插件自制

    插件描述 一行代码在你想要的位置生成一个轮播图 插件使用说明 import插件 在html页面中书写一个容器(即调...

  • Day05(组件,轮播图插件)

    组件,插件 demo 轮播图插件

  • jquery插件

    swiper图片轮播图插件

  • 使用vue-awesome-swiper方法

    在main.js中引入轮播图插件 在基础组件中建立轮播图组件:

  • 原生JS终极版-无缝轮播图

    现在大家一般很少自己用原生写轮播图,毕竟现在对于轮播图的插件各式各样,功能都很强大,在我看来功能最强大的轮播图插件...

  • jQuery相关插件

    jQuery全屏滚动插件fullPage.js jquery轮播图插件unslider

  • JavaScript 轮播图插件

    鹤鹤轮播插件1.6.1 此插件为初级版本,时刻保持更新 插件介绍:此插件可以直接生成轮播图,参数可调,内容自适应,...

  • Vue.js

    Target 01.常用插件:vue-awesome-swiper轮播图插件、 ***路由插件Router:基础:...

  • react-native 中常用插件

    轮播图插件:react-native-swiper Tabbar插件:react-native-tab-navig...

  • 常用插件

    js 插件 1,myFocus 焦点图插件===专注焦点图的js 库(轮播图)轻量级 http://demo.jb...

网友评论

      本文标题:ES6轮播图插件自制

      本文链接:https://www.haomeiwen.com/subject/yqojyktx.html