js原生实现轮播图效果(面向对象编程)
面向对象编程js原生实现轮播图效果
1.先看效果图

2.需要实现的功能:
- 自动轮播
- 点击左右箭头按钮无缝轮播
- 点击数字按钮切换图片
分析:如何实现无缝轮播?
在一个固定大小的相框里有一个ul标签,其长度是几个图片宽度的总和,通过translateX()的方法来实现左右移动动画。
如何实现无缝呢?比如有三张图片,可以在把第一张图片通过cloneNode的方法克隆下来放到第三张图片后面。图片顺序 1,2,3,1,看下面的HTML结构,结构中并没有4张图,第四张图是生成的。
3.html结构
<!-- ul是图片盒子,ol是数字按钮盒子,最下面的div是左右箭头按钮盒子 -->
<div class="container">
<div id="screen">
<ul>
<li><img src="./img/1.jpg" alt=""></li>
<li><img src="./img/2.jpg" alt=""></li>
<li><img src="./img/3.jpg" alt=""></li>
</ul>
<ol>
<!--<li class="active">1</li>-->
<!--<li>2</li>-->
<!--<li>3</li>-->
</ol>
</div>
<div>
<span><</span>
<span>></span>
</div>
</div>
4.功能实现
4.1 创建对象
创建一个对象,需要传入一个相框盒子元素,通过这个元素来获取盒子中其他需要的元素,并把这些作为这个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初始化方法
初始化方法中创建节点,绑定事件,同时设定定时器实现自动轮播效果。
// 初始化
Carousel.prototype.init = function () {
this.createNodes();
this.bindEvent();
this.timeId = setInterval(this.clickHandle.bind(this), 2000);
// 注意这里要bind(this) 否则clickHandle中的this指向window
};
4.8实例化Carousel对象,大功告成
实例化一个轮播图对象,然后调该对象的init方法。
只要html结构相同,只需要传入不同的相框元素,就可以在同一个页面中实例化多个轮播图对象。也就是说,同一个页面的多处轮播效果。
let carousel = new Carousel(document.getElementById('screen'));
carousel.init();
5备注
全部的代码和css样式可参考我的github中的轮播图仓库,菜鸟程序猿一枚,程序设计如果有不妥的地方欢迎提出意见或建议,当然啦,如果你喜欢并star了我的这个仓库,我会很开心的 : )
[1]: https://github.com/jiangleiundo/carousel
js原生实现轮播图效果(面向对象编程)的更多相关文章
- JS学习笔记--轮播图效果
希望通过自己的学习收获哪怕收获一点点,进步一点点都是值得的,加油吧!!! 本章知识点:index this for if else 下边我分享下通过老师教的方式写的轮播图,基础知识实现: 1.css代 ...
- jquery.flexslider-min.js实现banner轮播图效果
实现方法 引用jQuery和flexslider.js到你的页面 <script type="text/javascript" src="js/jquery-1.7 ...
- js原生的轮播图
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <t ...
- JS+css3焦点轮播图PC端
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 自己用原生JS写的轮播图,支持移动端触屏滑动,面向对象思路。分页器圆点支持click和mouseover。
自己用原生javascript写的轮播图,面向对象思路,支持移动端手指触屏滑动.分页器圆点可以选择click点击或mouseover鼠标移入时触发.图片滚动用的setInterval,感觉setInt ...
- js实现轮播图效果(附源码)--原生js的应用
1.js实现轮播图效果 <!DOCTYPE html><html lang="en"><head> <meta charset=" ...
- 原生JS实现简易轮播图
原生JS实现简易轮播图(渐变?) 最近做网页总是会用到轮播图,我就把之前写的轮播图单独拿出来吧,如果有...如果真的有人也需要也可以复制去用用啊..哈~.. window.onload = funct ...
- js 实现淘宝无缝轮播图效果,可更改配置参数 带完整版解析代码[slider.js]
前言: 本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽. 本篇文章为您分析一下原生JS写淘宝无缝轮播图效果 需求分析: ...
- jQuery与原生js实现banner轮播图
jQuery与原生js实现banner轮播图: (jq需自己加载)(图片需自己加载) <!DOCTYPE html> <html> <head> <meta ...
随机推荐
- 日期工具类 DateUtils(继承org.apache.commons.lang.time.DateUtils类)
/** * */ package com.dsj.gdbd.utils.web; import org.apache.commons.lang3.time.DateFormatUtils; impor ...
- node.js redis对事务的控制
redis对事务的支持还是比较差的,就是把所有的执行命令方到队列中一个一个执行 multi开启一个事务,exec执行事务集合中的命令 代码: var redisClient; redisClient. ...
- (转)通过汇编语言实现C协程
转自:http://www.cnblogs.com/sniperHW/archive/2012/06/19/2554574.html 协程的概念就不介绍了,不清楚的同学可以自己google,windo ...
- linux apt-get remove如何恢复
linux卸载或删除软件时,若不小心删除到关联的软件,如果想撤销删除操作需要在/var/log/apt/history.log中依次安装删除的软件,具体操作如下: $echo '#!/bin/bash ...
- Tomcat报错:HTTP Status 500 - Wrapper cannot find servlet class
HTTP Status 500 - Wrapper cannot find servlet class com.servlet.servlet.RegServlet or a class it dep ...
- 关于MFC预处理命令
MFC程序生成EXE文件的过程是:预处理-编译-链接-打包生成exe文件.(预编译是编译过程,即将一些常用的不经常改变的文件先进行编译处理生成中间文件,以节省时间,它不属于预处理,在VS项目属性的C/ ...
- Java读取文件的时候,如何让指针重新回到文件的开头
今天在测试IO流的使用的时候发现在reader读取文件之后,再向文件添加内容,再继续读文件,打印出的结果只能读取追加的文件. 如何才能重新读取呢?试了mark和reset,似乎会报异常.记在这以后看是 ...
- ffmpeg 纯静态编译,以及添加自定义库流程摘要
需求: 1. 纯静态编译ffmpeg ,即ldd ./ffmpeg 的结果是:not a dynamic executable 2. 修改ffmpeg 项目,添加自定义功能库 3. ...
- WC2010 BZOJ1758 重建计划_长链剖分
题目大意: 求长度$\in [L,U]$的路径的最大边权和平均值. 题解 首先二分就不用说了,分数规划大家都懂. 这题有非常显然的点分治做法,但还是借着这个题学一波长链剖分. 其长链剖分本身也没啥,就 ...
- QT(4)信号与槽
mainWidget.h #ifndef MAINWIDGET_H #define MAINWIDGET_H #include <QWidget> #include <QPushBu ...