轮播图(面向对象)

时间:2025-01-15 12:44:46
import LoadImage from "./"; import Utils from "./"; export default class Carousel { imgList; //轮播图图片放入ingList数组中 w; h; bnlist; //存放左右点击按钮的图片 list; //存放只含有轮播图图片的数组 imageCon; //存放两张图片隐藏在轮播图后边,通过调整定位改变位置,进而实现轮播图 parent; //父元素 dot; //轮播图下部点击小圆点整体ul图 dotList = []; //轮播图下部点击小圆点li存入数组 pos = 0; //通过pos 记录当前为第几张图片 direction = ""; //记录轮播图转换时图片移动方向 bool = false; //控制图片是否转换,转换开关 x = 0; //控制imageCon left的值 speed = 0.5; // 控制imageCon移动速度 autoBool = false; //图片自动轮播开关 time = 200; //设置防抖 200次执行一次 pre; //设置下部小圆点 背景颜色透明度 static carouselList = []; //存放轮播图,可以设置多个轮播图,然后添加到数组内 constructor(_imgList) { this.imgList = _imgList; //创建播放轮播图的div this.carousel = this.createCarousel(); //预缓存图片,并且全部缓存完成后执行finishHandler函数,此时图片已经是一个图片元素了 new LoadImage(_imgList, (list) => this.finishHandler(list)); //将创建的轮播图放入静态数组内 Carousel.carouselList.push(this); } //将元素放入给定的父元素内 appendTo(parent) { if (parent.constructor === String) parent = document.querySelector(parent); parent.appendChild(this.carousel); this.parent = parent; } //图片全部预缓存结束后执行的函数 finishHandler(_list) { //将预缓存后存放浅复制图片的数组删除后两位,即删除左右按钮两张图片,将删除的两张图片存入新数组内 this.bnlist = _list.splice(-2); //如果w不存在,给w赋予轮播图第一张图片的宽和高 if (!this.w) { this.w = _list[0].width / 100; this.h = _list[0].height / 100; } // 到此为止w和h正式全部确认完毕 this.list = _list.map((item) => { item.style.width = this.w + "rem"; item.style.height = this.h + "rem"; return item; }); //给carousel设置宽高 Object.assign(this.carousel.style, { width: this.w + "rem", height: this.h + "rem", }); //图片全部加载完成后执行以下函数 this.createImageCon(); this.createBn(); this.createDot(); this.changePre(); } //setWH函数 :设置图片宽高 setWH(_w, _h) { //如果图片加载完成,直接返回 if (!this.parent) return; //如果传入的参数为布尔值 if (_w.constructor === Boolean) { //如果第一个为true if (_w) { //则以父元素的宽作为图片的宽,高为宽的一半 var rect = this.parent.getBoundingClientRect(); this.w = rect.width / 100; this.h = this.w / 3; } //如果第一个参数为数值型,宽高为 传入的参数 } else if (_w.constructor === Number) { this.w = _w / 100; this.h = _h / 100; } } //创建轮播图容器 createCarousel() { var carousel = Utils.ce("div", { position: "relative", margin: "auto", overflow: "hidden", left: 0, right: 0, backgroundColor: "rgba(255,0,0,0.1)", }); //为轮播图容器设置鼠标滑入和鼠标滑出事件,用来实现 轮播图自动播放 carousel.addEventListener("mouseenter", (e) => this.mouseHandler(e)); carousel.addEventListener("mouseleave", (e) => this.mouseHandler(e)); return carousel; } //创建图片存放的div,存放两张图片,以实现图片实现 createImageCon() { this.imageCon = Utils.ce("div", { width: this.w * 2 + "rem", height: this.h + "rem", position: "absolute", left: 0, }); //将第一张图片放入图片存放容器中 this.imageCon.appendChild(this.list[0]); //将图片存放容器放入轮播图div中 this.carousel.appendChild(this.imageCon); } //创建左右按钮 createBn() { //遍历存放左右按钮的数组,并且给图片元素添加CSS样式 this.bnlist.forEach((item, index) => { Object.assign(item.style, { position: "absolute", left: index === 0 ? "20px" : "none", right: index === 1 ? "20px" : "none", top: (this.h - item.height / 100) / 2 + "rem", }); //给左右按钮添加点击事件 item.addEventListener("click",e => this.clickHandler(e)); //将左右按钮添加到轮播图容器里 this.carousel.appendChild(item); }); } createDot() { //创建存放轮播图下方小按钮的ul this.dot = Utils.ce("ul", { listStyle: "none", margin: "0px", padding: "0px", position: "absolute", bottom: "0.2rem", }); //根据存放图片数组的长度创建小按钮li this.list.forEach((item, index) => { var li = Utils.ce( "li", { width: "0.15rem", height: "0.15rem", backgroundColor: "rgba(255,0,0,0)", border: "1px solid #FF0000", borderRadius: "0.15rem", float: "left", marginLeft: index === 0 ? 0 : "0.1rem", }, this.dot ); //将创建的li放入dotList数组内 this.dotList.push(li); }); //将小按钮添加到轮播图容器内 this.carousel.appendChild(this.dot); //给小按钮设置位置 this.dot.style.left = (this.w - this.dot.offsetWidth / 100) / 2 + "rem"; //给小按钮添加点击事件 this.dot.addEventListener("click", (e) => this.clickDotHandler(e)); } //左右按钮触发后执行的函数 clickHandler(e) { if(this.bool) return; //如果侦听的元素为左右按钮数组内的第0为 即左按钮时 if (this.bnlist.indexOf(e.currentTarget) === 0) { //pos-1,pos为轮播图图片的“编号”,图片依靠pos改变。 this.pos--; //如果pos小于零说明左侧没有图片了,pos等于最右侧图片“编号” if (this.pos < 0) this.pos = this.list.length - 1; //图片此时向右滑动 this.direction = "right"; } //else即为右按钮 else { //pos的值+1 this.pos++; //如果pos大于了图片的个数,则右侧没有图片了,pos等于最左侧图片的“编号”,即0 if (this.pos > this.list.length - 1) this.pos = 0; //此时pos向左移动 this.direction = "left"; } //然后执行图片切换函数 this.createNextImage(); } //点击下方小按钮执行的函数 clickDotHandler(e) { if(this.bool) return; //委托事件,如果点击的元素不是li,直接返回 if (e.target.constructor !== HTMLLIElement) return; //声明index为点击的li在数组内的下标 var index = this.dotList.indexOf(e.target); //如果点击li的下标等于当前pos,即小按钮对应的图片一致时,直接返回 if (index === this.pos) return; //根据下标和pos的大小判断点击li后图片应该左移还是右移 this.direction = index > this.pos ? "left" : "right"; //然后将pos改为点击li的下标 this.pos = index; //执行更换图片的函数 this.createNextImage(); } //更换图片函数 createNextImage() { //如果移动方向为左 if (this.direction === "left") { //将在图片列表里下标为pos的图片元素插入到存放图片用来转换的容器内 this.imageCon.appendChild(this.list[this.pos]); this.imageCon.style.left = "0rem"; this.x = 0; } //如果移动方向为右 else { //在转换容器的最左侧插入下标为pos的图片元素 this.imageCon.insertBefore(this.list[this.pos], this.imageCon.firstChild); //然后将给转换容器定位为-w ,即把准备切换的图片切换到最左侧,以实现切换动画效果 this.imageCon.style.left = -this.w + "rem"; //x赋值为-w this.x = -this.w; } //将切换开关设置为true this.bool = true; //执行下方按钮背景图改变函数 this.changePre(); } changePre() { //如果pre存在,先把所有小圆点背景色设为透明 if (this.pre) { this.pre.style.backgroundColor = "rgba(255,0,0,0)"; } //然后给pre赋值为下标为pos的小圆点,并且将其背景色设置为0.6透明 this.pre = this.dotList[this.pos]; this.pre.style.backgroundColor = "rgba(255,0,0,0.6)"; } //鼠标滑入滑出事件执行的函数 mouseHandler(e) { //如果鼠标滑入,自动播放关闭,且防抖time设为200 if (e.type === "mouseenter") { this.autoBool = false; this.time = 200; } else { //如果鼠标滑出,开始自动播放 this.autoBool = true; } } //改变函数 update() { this.imgMove(); this.autoPlay(); } //图片转换函数 imgMove() { //判断容器是否移动,否的话直接返回 if (!this.bool) return; //如果移动方向为左 if (this.direction === "left") { //x值逐渐减少,即容器定位左移,显示图片左移效果 this.x -= this.speed; //当x<=-w时,x=0,关闭转换开关,,并且删除第一张在转换容器的图片 if (this.x <= -this.w) { this.x = 0; this.bool = false; this.imageCon.firstElementChild.remove(); } //转换容器定位到x this.imageCon.style.left = this.x + "rem"; } else { //右移时,x值从-w逐渐增大,即容器右移,图片右移效果 this.x += this.speed; //当x>=0时,x=0,关闭转换开关,删除之前图片 if (this.x >= 0) { this.x = 0; this.bool = false; this.imageCon.lastElementChild.remove(); } //转换容器定位到x=0 this.imageCon.style.left = this.x + "rem"; } } //自动播放函数 autoPlay() { //如果开关为关,即鼠标滑入,直接返回 if (!this.autoBool) return; this.time--; //如果开关为开,即鼠标滑出,抛发给右按钮点击事件 if (this.time > 0) return; this.time = 200; var evt = new MouseEvent("click"); this.bnlist[1].dispatchEvent(evt); } //静态改变方法,可以给全部的轮播图实现改变 static UPDATE() { for (var i = 0; i < Carousel.carouselList.length; i++) { Carousel.carouselList[i].update(); } } }