JS轮播图案例
weixin_51276799 人气:0实现功能:
1、自动轮播:鼠标停留在轮播图上时不切换图片,鼠标离开后自动轮播。
2、点击左右按钮切换图片。
3、点击下方按钮切换到对应的图片。
4、轮播图大小自适应:
可以放入到执行的父容器中展示。
不指定父容器时,默认放入body标签。占满一屏的宽度,当改变浏览器窗口大小时,轮播图大小成比例改变。
可以指定轮播图的宽高。
实现方式:用面向对象的方式实现,使用时传入图片和图片对应的数据,再创建实例。
import Carousel from './js/Carousel.js'; var itemList1 = [{ day: 26, date: "/Oct.2020", title: "秘境之蓝 无阿里不西藏 自驾阿里小北线", src: "./carousel_img/a.jpg", }, { day: 25, date: "/Oct.2020", title: "这是一个什么样的国家?", src: "./carousel_img/b.jpg", }, { day: 24, date: "/Oct.2020", title: "在徽州,给秋天写了8封信", src: "./carousel_img/c.jpg", }, { day: 23, date: "/Oct.2020", title: "「穿过狂野的风」赶赴内蒙的追羊计划", src: "./carousel_img/d.jpg", }, { day: 22, date: "/Oct.2020", title: "爱让我们无所不能|南极大冒险", src: "./carousel_img/e.jpg", }, ]; let carousel1 = new Carousel(itemList1); carousel1.appendTo(".div1"); animation(); function animation(){ requestAnimationFrame(animation); carousel1.update(); // carousel2.update(); }
代码:
import Component from './Component.js'; export default class Carousel extends Component{ imgList; bnList; imgCon; dot; dotList=[]; data; direction; pos=0; x=0; speedX=1; bool=false; time=200; autoBool=true; // WIDTH=13.66; // HEIGHT=4.55; WIDTH; HEIGHT; constructor(_data,_width,_height){ super("div"); this.data=_data; this.width = _width; this.height = _height; this.elem.className = "carousel"; // Object.assign(this.elem.style,{ // width:this.WIDTH+"rem", // height:this.HEIGHT+"rem", // position:"relative", // overflow:"hidden", // }); let arr = ["./carousel_img/left.png","./carousel_img/right.png"]; let _imgList = this.data.reduce((value,item)=>{ if(item.src) value.push(item.src); return value },arr); this.loadImg(_imgList,this.createCarousel); // window.addEventListener("resize",e=>this.resizeHandler(e)); } createCarousel(imgList){ Object.assign(this.elem.style,{ width:this.WIDTH+"rem", height:this.HEIGHT+"rem", position:"relative", overflow:"hidden", }); this.imgList = imgList; this.bnList = this.imgList.splice(0,2); imgList.forEach(item=>{ Object.assign(item.style,{ width:this.WIDTH+"rem", height:this.HEIGHT+"rem", }) }) this.createimgCon(); this.createDotList(); this.createBn(); // 动画一般在外面做,类里面只需要写状态更新即可。 // this.animation(); // 鼠标停留在轮播图上时不进行自动轮播。 this.elem.addEventListener("mouseenter",e=>this.mouseHandler(e)); this.elem.addEventListener("mouseleave",e=>this.mouseHandler(e)); } createimgCon(){ this.imgCon = document.createElement("div"); Object.assign(this.imgCon.style,{ width:this.WIDTH*2+"rem", height:this.HEIGHT+"rem", position:"absolute", }); let item = this.createItem(this.imgList[0],this.data[0]); this.imgCon.appendChild(item); this.elem.appendChild(this.imgCon); } createItem(img,obj){ let item = document.createElement("div"); Object.assign(item.style,{ width:this.WIDTH+"rem", height:this.HEIGHT+"rem", position:"relative", float:"left", }); let title = document.createElement("div"); Object.assign(title.style,{ position:"absolute", left:"15%", top:"0.3rem", fontSize:"0.3rem", color:"#ffffff", textShadow:"0.02rem 0.02rem 0.02rem #000000", width:"8rem", lineHeight:"0.5rem", }) let head1=document.createElement("div"); Object.assign(head1.style,{ height:"0.5rem", }) head1.textContent = obj.date; let span = document.createElement("span"); Object.assign(span.style,{ fontSize:"0.4rem", }); span.textContent = obj.day; let head2 = document.createElement("div"); Object.assign(head2.style,{ height:"0.5rem", }) head2.textContent = obj.title; head1.insertBefore(span,head1.firstChild); title.appendChild(head1); title.appendChild(head2); item.appendChild(title); item.appendChild(img); return item; } createDotList(){ this.dot = document.createElement("ul"); Object.assign(this.dot.style,{ listStyle:"none", margin:0, padding:0, position:"absolute", left:(this.WIDTH-1.8)/2+"rem", bottom:"0.3rem", }) for(let i=0;i<this.imgList.length;i++){ let li = document.createElement("li"); Object.assign(li.style,{ width:"0.18rem", height:"0.18rem", borderRadius:"0.2rem", marginLeft:i===0?"0px":"0.2rem", border:"0.02rem solid red", float:"left", }) this.dot.appendChild(li); this.dotList.push(li); } this.dot.addEventListener("click",e=>this.dotClickHandler(e)); this.elem.appendChild(this.dot); } createBn(){ for(let i=0;i<this.bnList.length;i++){ Object.assign(this.bnList[i].style,{ position:"absolute", top:(this.HEIGHT*100-this.bnList[i].height)/2/100+"rem", }) if(i===0){ this.bnList[i].style.left = "0.5rem"; }else{ this.bnList[i].style.right = "0.5rem"; } this.bnList[i].addEventListener("click",e=>this.bnClickHandler(e)); this.elem.appendChild(this.bnList[i]); } } bnClickHandler(e){ if(this.bool) return if(e.target===this.bnList[0]){ this.direction="left"; this.pos++; if(this.pos>this.imgList.length-1) this.pos = 0; }else{ this.direction="right"; this.pos--; if(this.pos<0) this.pos=this.imgList.length-1; } this.bool=true; this.createNextItem(); } dotClickHandler(e){ if(e.target.constructor!==HTMLLIElement) return //这里因为是对父元素进行侦听,因此要先判断点击的是不是li,如果点击的不是小圆点就不能改变开关,直接return。不能先改变开关。 if(this.bool)return for(let i=0;i<this.dotList.length;i++){ if(e.target===this.dotList[i]){ if(this.pos===i) return this.direction=i<this.pos?"right":"left"; this.pos=i; } } this.bool=true; this.createNextItem(); } createNextItem(){ let nextItem=this.createItem(this.imgList[this.pos],this.data[this.pos]); if(this.direction==="left"){ this.imgCon.appendChild(nextItem); this.x=0; }else{ this.imgCon.insertBefore(nextItem,this.imgCon.firstChild); this.x=-this.WIDTH; } this.imgCon.style.left=this.x+"rem"; } update(){ this.imgMove(); this.autoPlay(); } // 这里只需要做一个状态更新即可。 // 动画在外面做。 // animation(){ // requestAnimationFrame(this.animation); // if(!this.bool) return // this.imgMove(); // } imgMove(){ if(!this.bool) return if(this.direction==="left"){ this.x-=this.speedX; if(this.x<-this.WIDTH){ this.imgCon.firstElementChild.remove(); this.x=0; this.bool=false; } }else{ this.x+=this.speedX; if(this.x>0){ this.imgCon.lastElementChild.remove(); this.x=0; this.bool=false; } } this.imgCon.style.left=this.x+"rem"; } autoPlay(){ if(!this.autoBool) return this.time--; //增加防抖 if(this.time===0){ let evt = new Event("click"); this.bnList[0].dispatchEvent(evt); this.time=200; } } resizeHandler(e){ document.documentElement.style.fontSize=document.documentElement.clientWidth/(this.WIDTH*100)*100+"px"; } appendTo(parent){ if(typeof parent==="string") parent = document.querySelector(parent); parent.appendChild(this.elem); if(!isNaN(this.WIDTH) && !isNaN(this.HEIGHT)) return if(parent===document.body){ this.WIDTH = 13.66; this.HEIGHT = 4.55; }else{ let rect = parent.getBoundingClientRect(); this.WIDTH=rect.width/100; this.HEIGHT=rect.height/100; } } mouseHandler(e){ if(e.type==="mouseenter"){ this.autoBool=false; }else{ this.autoBool=true; } } // 图片预加载 loadImg(_imgList,_callBack){ let img = new Image(); img.i=0; img.arr=[]; img.imgList=_imgList; // img.callBack=_callBack; img.src=_imgList[img.i]; img.addEventListener("load",e=>this.imgLoadFinishHandler(e)); } imgLoadFinishHandler(e){ // console.log(e.currentTarget); e.currentTarget.arr.push(e.currentTarget.cloneNode()); e.currentTarget.i++; if(e.currentTarget.i<e.currentTarget.imgList.length){ e.currentTarget.src = e.currentTarget.imgList[e.currentTarget.i]; }else{ // e.currentTarget.callBack(e.currentTarget.arr); this.createCarousel(e.currentTarget.arr); } } }
加载全部内容