面向对象编程js原生实现轮播图效果 1.先看效果图
2.需要实现的功能:自动轮播
点击左右箭头按钮无缝轮播
点击数字按钮切换图片
分析:如何实现无缝轮播?
在一个固定大小的相框里有一个ul标签,其长度是几个图片宽度的总和,通过translateX()的方法来实现左右移动动画。
如何实现无缝呢?比如有三张图片,可以在把第一张图片通过cloneNode的方法克隆下来放到第三张图片后面。图片顺序 1,2,3,1,看下面的HTML结构,结构中并没有4张图,第四张图是生成的。
创建一个对象,需要传入一个相框盒子元素,通过这个元素来获取盒子中其他需要的元素,并把这些作为这个Carousel对象的属性:
function Carousel(el) { this.screen = el; // 相框 this.width = this.screen.offsetWidth; // 相框宽度 this.ulBox = this.screen.children[0]; // ul盒子 this.list = this.ulBox.children; // ul下面所有li this.olBox = this.screen.children[1]; // 数字按钮盒子 this.arrow = this.screen.nextElementSibling; // 箭头盒子 this.leftArraw = this.arrow.children[0]; // 左箭头 this.rightArraw = this.arrow.children[1]; // 右箭头 this.index = 0; // 数字按钮的索引 this.timeId = null; // 定时器的id this.activeClass = \'active\'; // 数字按钮class名 this.durtion = \'.35s\'; // 动画持续时间 } 4.2动画效果由translateX实现 // 动画 Carousel.prototype.animate = function (target) { this.ulBox.style.transform = \'translateX(\' + target + \'px)\' }; 4.3根据轮播图片个数生成数字按钮节点生成节点后,为新生成的节点添加点击事件,实现每次点击根据节点对应的index切换图片,这里实现的需求的第三个功能。
// 创建节点 Carousel.prototype.createNodes = function () { let self = this; // 创建按钮节点 for (let i = 0; i < self.list.length; i++) { let liObj = document.createElement(\'li\'); liObj.innerText = i + 1; self.olBox.appendChild(liObj); // 为生成的数字按钮添加点击事件 liObj.onclick = function () { self.index = this.innerText - 1; // 获取当前点击对象的索引值 self.switch_sel(); self.animate(-self.index * self.width); }; } // 默认显示第一张图片,第一个数字按钮默认选中状态 self.olBox.children[0].className = self.activeClass; // 克隆第一张图放到ulBox后面,实现无缝轮播 self.ulBox.appendChild(self.ulBox.children[0].cloneNode(true)); }; 4.4轮播图数字按钮点击切换状态因为多次用到这段代码,所有就写成一个方法挂在Carousel对象上了
// 切换数字按钮的选中状态 Carousel.prototype.switch_sel = function(){ let self = this; for (let i = 0; i < self.olBox.children.length; i++) { self.olBox.children[i].removeAttribute(\'class\'); } self.olBox.children[self.index].className = self.activeClass; }; 4.5轮播事件,也是点击右箭头的事件 // 轮播事件 Carousel.prototype.clickHandle = function () { let self = this; // 如果是最后一张图,直接跳到第一张 if (self.index === self.list.length - 1) { self.index = 0; // 当点击到最后一张时直接跳到第一张 self.ulBox.style.transitionDuration = \'0s\'; self.animate(-self.index * self.width); } // 必须有时间延迟,否则图片跳转切换不成功,因为self.animate()没有来得及执行就被后面的self.animate()函数覆盖了。 setTimeout(function () { self.ulBox.style.transitionDuration = self.durtion; self.index++; self.animate(-self.index * self.width); // 如果是最后一张图,则去掉最后一个的class属性,切换到第一个 if (self.index === self.list.length - 1) { self.olBox.children[self.olBox.children.length - 1].removeAttribute(\'class\'); self.olBox.children[0].className = self.activeClass; } else { // 切换当前选中状态 self.switch_sel(); } }, 20); }; 4.6事件绑定为左右箭头点击绑定事件,同时当鼠标hover在相框上时自动轮播取消,鼠标离开相框时自动轮播开始执行。
// 事件绑定 Carousel.prototype.bindEvent = function () { let self = this; // 又点击下一张 self.rightArraw.onclick = function () { self.clickHandle(); }; // 左点击上一张 self.leftArraw.onclick = function(){ if(self.index === 0){ self.index = self.list.length - 1; // 直接跳到最后一张 self.ulBox.style.transitionDuration = \'0s\'; self.animate(-self.index * self.width); } setTimeout(function(){ self.ulBox.style.transitionDuration = self.durtion; self.index--; self.animate(-self.index * self.width); self.switch_sel(); }, 20); }; // 鼠标悬停清除定时器 self.screen.parentElement.onmouseover = function(){ self.timeId && clearInterval(self.timeId); self.arrow.style.display = \'flex\'; }; // 鼠标离开打开定时器 self.screen.parentElement.onmouseout = function(){ self.timeId = setInterval(self.clickHandle.bind(self), 2000); self.arrow.style.display = \'none\'; } }; 4.7初始化方法