js代码实现轮播图


Posted in Javascript onMay 04, 2020

本文实例为大家分享了js实现轮播图的具体代码,供大家参考,具体内容如下

又从头到尾把轮播图研究了一遍,感觉理解更深刻了。
就怕自己搞不懂,分析了各个步骤的思路,为啥用,怎么用。
总算搞清楚了。
话不多说,干货奉上.

效果图:

js代码实现轮播图

//1,左右按钮初始隐藏 鼠标进入box 按钮显示 鼠标离开box 按钮隐藏
//获取元素
var box = document.getElementById('box');
var leftbtn = document.getElementById('leftbtn');
var rigbtn = document.getElementById('rigbtn');
//因为图片宽度是多个事件需要用到 所以要定义为全局变量
var pic_width = box.clientWidth;
//注册事件
box.addEventListener('mouseenter', function() {
 leftbtn.style.display = 'block';
 rigbtn.style.display = 'block';
 //清除定时器 停止自动播放 
 clearInterval(timer);
 //停止播放后 清空定时器变量 提升运行效率
 timer = null;
});
box.addEventListener('mouseleave', function() {
 leftbtn.style.display = 'none';
 rigbtn.style.display = 'none';
 //timer在11条里声明过了 这里就不需要再加var进行声明了
 timer = setInterval(function() {
 rigbtn.click();
 }, 1500);
});
//6,创建动画函数animate 点击小圆点 图片会移动 
//因为图片需要缓慢移动到目标位置 而不是瞬移 所以需要让动画函数带缓动效果
function animate(obj, target, callback) {
 //obj是移动的对象 target是移动的目标位置 callback是回调函数
 clearInterval(obj.timer);
 //创建缓动函数 缓动的核心思想就是把移动到目标位置的距离分成若干小步
 //一定时间内走一小步,让这个距离在若干时间完成若干小步后走完
 function move() {
 //定义每一小步走的距离 把一次移动到目标位置的距离分为10份
 //每一份就是一个step
 var step = (target - obj.offsetLeft) / 10;
 //step可能不是整数 导致最终移动距离有误差 
 //所以要把每一步的step变成整数
 //如果step是正数 就取大于step的最小整数
 //如果step是负数 就取小于step的最大整数 用Math()的知识
 /*if(step > 0) {
 step = Math.ceil(step);//向上取整
 } else {
 step = Math.floor(step);//向下取整
 }*/
 //可以将上面的if else语句简化为三元运算符
 step = step > 0 ? Math.ceil(step) : Math.floor(step);
 //如果走到了目标位置 就清除定时器
 if(obj.offsetLeft == target) {
 clearInterval(obj.timer);
 //因为回调函数是定时器结束后再调用函数 
 //所以这里清除定时器后 需要判断一下是否有回调函数 有就调用 没有就不调用
 /*if(callback) {
 callback();
 }*/
 //上面的判断语句可以简化为
 callback&&callback();
 }
 //把每一小步移动的距离和offsetLeft之和,给obj的left值
 //注意,这里obj.style.left对应的是数值+像素单位,一定不要忘了+'px'
 obj.style.left = obj.offsetLeft + step + 'px';
 }
 //给obj创建专属的定时器 
 //用定时器实现一定时间走一小步的结果 这里是40毫秒移动一个step的距离
 //注意,专属定时器不需要用var了 
 obj.timer = setInterval(move, 40);
}
//2,动态添加小圆点 图片的数量就是小圆点的个数
//获取元素
var ul01 = document.getElementById('ul01');
var ul02 = document.getElementById('ul02');
//添加多个li 用for循环 
for(var i = 0; i < ul01.children.length; i++) {
 //创建元素creLi
 var creLi = document.createElement('li');
 //3,创建自定义属性data-index 用来获取小圆点的索引号
 creLi.setAttribute('data-index', i); 
 //添加元素
 ul02.appendChild(creLi);
 //4,当前点击的小圆点 颜色发生变化 创建类urrent
 //因为图片默认开始显示第一张 所以先让第一个小圆点小时current类
 ul02.children[0].className = 'current';
 //5,给小圆点创建点击事件 点击小圆点 当前点击的小圆点变色
 //用排他思想 for循环
 //注册点击事件
 creLi.addEventListener('click', function() {
 //干掉所有人
 for(var i = 0; i < ul02.children.length; i++) {
 ul02.children[i].className = '';
 }
 //留下我自己
 this.className = 'current';
 //7,点击小圆点 图片跟着动 调用动画函数
 //分析 点击圆点1 图片向左移动0个图片的宽度box.clientWidth
 //点击圆点2 图片向左移动1个图片的宽度 以此类推
 //图片移动的距离 就是 当前被点击圆点的索引号乘以图片的宽度
 
 //获取自定义属性 当前被点击的小圆点的索引号
 var index = this.getAttribute('data-index');
 num = index;
 circle = index;
 animate(ul01, -index*pic_width);
 });
}
//8,右侧按钮
//8.1 点击右侧按钮 图片向左移动
//点击1次 图片向左移动1个图片宽度 显示图片2
//点击2次 向左移动2个图片宽度 显示图片3 以此类推
//当显示到第3张图片即最后一张图片时 再点击右侧按钮 会显示空白
//重点: 实现无缝链接,即当显示到最后一张图片时 再点击右侧按钮 会显示图片1
//怎么做 在图片3后面克隆一张图片1
//显示图片3时 再点击按钮 ul01继续向左移动 显示图片1
//然后迅速跳转到跳转到图片1 让ul01.style.left归零
//设置次数变量num
var num = 0;
//克隆图片1 先克隆 再添加 注意 克隆图片也是全局事件 不是局部的
var liCopy = ul01.children[0].cloneNode(true)//深克隆
ul01.appendChild(liCopy);//添加新的li后,注意取css里修改ul01的宽度
//console.log(ul01.children.length); 元素个数变成了4
//获取元素rigbtn
var rigbtn = document.getElementById('rigbtn');
//给按钮点击事件安装节流阀
var flag = true; //左右按钮都要用 所以设置全局变量

//注册点击事件
rigbtn.addEventListener('click', function() {
 if(flag) {
 //初始状态 先把节流阀关了 让自动播放的图片播放完一张图片前 点击按钮无效
 flag = false;
 //先做个判断 
 //点击第2次的时候 显示图片3 再点击 就显示克隆的图片1 
 //这时候 让ul01位置归零 让num的值归零以便从头开始
 if(num == ul01.children.length - 1) {
 ul01.style.left = 0;
 num = 0;
 }
 //点击1次 移动距离就是1*pic_width
 //点击1次 让num自增1
 num++;
 //注意 这里如果先自增 再做判断
 //会出现一个bug 就是当再次显示图片1时 点击无效 重新点击才会显示图片2
 //因为点击第三次时 本来应该跳转到图片1的 结果num被归零了 再点击还是显示图片1
 //调用动画函数
 
 animate(ul01, -num*pic_width, function() {
 //function(){}是回调函数
 //动画结束一个动作后 即播放完该图片后 再回头打开节流阀 让下一次点击生效
 flag = true;
 });
 circle++;
 if(circle == ul02.children.length) {
 circle = 0;
 }
 //因为这段排他思想的小圆点代码重复使用 所以可以封装成一个函数进行调用
 /*for(var i = 0; i < ul02.children.length; i++) {
 ul02.children[i].className = '';
 }
 ul02.children[circle].className = 'current';*/
 cir();
 }
}); 

function cir() {
 for(var i = 0; i < ul02.children.length; i++) {
 ul02.children[i].className = '';
 }
 ul02.children[circle].className = 'current';
}
//9,点击按钮 图片移动 小圆点跟着移动 点击小圆点 图片跟着移动 num次数也变化
//让图片 小圆点 按钮次数 一起变化的核心 就是图片动 num变化 小圆点当前的current类发生变化
//即 图片移动 当前小圆点变色 点击按钮 当前小圆点变色
//当前小圆点变色 图片移动 按钮次数发生变化 num index 图片距离 一起变化 
//但是index是局部变量 怎么让三者绑定呢
//就要重新创建一个全局变量 代替index 作为小圆点当前的索引号 让三者绑定
var circle = 0;
//10,点击左侧按钮
//和右侧按钮点击事件的代码基本相同 但是方向相反 需要修改一些数据
//直接把右侧按钮点击事件的代码复制过来 然后修改数据
//获取元素leftbtn
var leftbtn = document.getElementById('leftbtn');
//注册点击事件
leftbtn.addEventListener('click', function() {
 //同理,给左侧按钮也加个节流阀
 if(flag) {
 flag = false;
 //先做个判断 
 //开始时 未点击 num为0
 if(num == 0) {
 num = ul01.children.length-1;
 ul01.style.left = -num*pic_width + 'px';
 }
 //点击左侧按钮时 num自减
 num--;
 
 animate(ul01, -num*pic_width, function() {
 flag = true;
 });
 circle--;
 if(circle < 0) {
 circle = ul02.children.length - 1;
 }
 //因为这段排他思想的小圆点代码重复使用 所以可以封装成一个函数进行调用
 /*for(var i = 0; i < ul02.children.length; i++) {
 ul02.children[i].className = '';
 }
 ul02.children[circle].className = 'current';*/
 cir();
 }
});
//11,图片自动播放 相当于每隔一定时间 用定时器调用点击右侧按钮的时间 
var timer = setInterval(function() {
 rigbtn.click();
}, 1500);
//12,鼠标进入box 停止自动播放 鼠标离开box 继续自动播放
//13,节流阀 控制图片播放的频率
//当前 快速点击按钮 图片高速播放 timer定时器还没执行结束 就开始播放下一张图片了
//用flag控制 flag为true 打开节流阀 启用定时器 播放图片
//flag为false 关闭节流阀 关闭的定时器 点击按钮无效 停止播放图片
//给按钮点击事件安装节流阀

精彩专题分享:jQuery图片轮播 JavaScript图片轮播 Bootstrap图片轮播

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Javascript 生成指定范围数值随机数
Jan 09 Javascript
JQuery Ajax 跨域访问的解决方案
Mar 12 Javascript
jquery实现图片裁剪思路及实现
Aug 16 Javascript
asm.js使用示例代码
Nov 28 Javascript
Bootstrap3制作图片轮播效果
May 12 Javascript
Javascript中常用的检测方法小结
Oct 08 Javascript
Javascript中内建函数reduce的应用详解
Oct 20 Javascript
Javascript实现倒计时时差效果
May 18 Javascript
Vue集成Iframe页面的方法示例
Dec 12 Javascript
js实现点击按钮复制文本功能
Jul 20 Javascript
vue弹窗组件使用方法
Apr 28 Javascript
谈谈IntersectionObserver懒加载的具体使用
Oct 15 Javascript
原生js实现轮播图特效
May 04 #Javascript
jquery实现手风琴案例
May 04 #jQuery
autojs 蚂蚁森林能量自动拾取即给指定好友浇水的实现方法
May 03 #Javascript
解决React在安装antd之后出现的Can't resolve './locale'问题(推荐)
May 03 #Javascript
vue自定义标签和单页面多路由的实现代码
May 03 #Javascript
JavaScript函数重载操作实例浅析
May 02 #Javascript
有趣的JavaScript隐式类型转换操作实例分析
May 02 #Javascript
You might like
PHP 开源AJAX框架14种
2009/08/24 PHP
php将数据库中所有内容生成静态html文档的代码
2010/04/12 PHP
Notice: Undefined index: page in E:\PHP\test.php on line 14
2010/11/02 PHP
浅析PHP Socket技术
2013/08/02 PHP
thinkPHP数据库增删改查操作方法实例详解
2016/12/06 PHP
基于ThinkPHP实现的日历功能实例详解
2017/04/15 PHP
关于 Laravel Redis 多个进程同时取队列问题详解
2017/12/25 PHP
PHP字符串与数组处理函数用法小结
2020/01/07 PHP
javascript 单例/单体模式(Singleton)
2011/04/07 Javascript
禁止页面刷新让F5快捷键及右键都无效
2014/01/22 Javascript
JavaScript类属性的访问方式详解
2014/02/11 Javascript
Web前端开发工具——bower依赖包管理工具
2016/03/29 Javascript
微信小程序(三):网络请求
2017/01/13 Javascript
JS实现复制内容到剪贴板功能
2017/02/05 Javascript
基于Vue2.X的路由和钩子函数详解
2018/02/09 Javascript
深入浅析js原型链和vue构造函数
2018/10/25 Javascript
js判断一个对象是数组(函数)的方法实例
2019/12/19 Javascript
ES5新增数组的实现方法
2020/05/12 Javascript
javascript实现前端分页功能
2020/11/26 Javascript
[01:18]DOTA2超级联赛专访hanci ForLove淘汰感言曝光
2013/06/04 DOTA
[07:48]DOTA2上海特级锦标赛主赛事首日RECAP
2016/03/04 DOTA
[04:51]TI10典藏宝瓶Ⅱ外观视频展示
2020/08/15 DOTA
[02:17]快乐加倍!DOTA2食人魔魔法师至宝+迎霜节活动上线
2019/12/22 DOTA
Python学习pygal绘制线图代码分享
2017/12/09 Python
Python断言assert的用法代码解析
2018/02/03 Python
python利用requests库模拟post请求时json的使用教程
2018/12/07 Python
Python字符串和正则表达式中的反斜杠('\')问题详解
2019/09/03 Python
Python上下文管理器用法及实例解析
2019/11/11 Python
python获取引用对象的个数方式
2019/12/20 Python
Python post请求实现代码实例
2020/02/28 Python
Python 合并拼接字符串的方法
2020/07/28 Python
HTML5对比HTML4的主要改变和改进总结
2016/05/27 HTML / CSS
阿姆斯特丹城市卡:Amsterdam Pass
2019/12/01 全球购物
小学防溺水制度
2014/01/29 职场文书
万年牢教学反思
2014/02/15 职场文书
Vue+TypeScript中处理computed方式
2022/04/02 Vue.js