轮播图已经成了页面开发中不可缺少的一部分,日常生活中随处都能见到轮播图的身影,例如平常我们购物的淘宝,京东等等,都靠着轮播图在一片 有限的区域内展现出更多的商品。这也是前端程序员最早接触到的练手小项目,这篇文章带大家透彻拿下轮播图!从此不再迷茫

首先我们来看一下本次案例的效果:

(下面有请本人女朋友出境!话说我是在搞不明白 gif 图怎么设置,但总之就是该有的功能都有,不该有的功能也有(例如杀狗 hhhhh),自动播放,点击切换按钮切换图片,点击下方圆点切换图片均可实现,就不一一演示了,主要还是让大家搞明白原理是什么)

我将拆分成下面几个步骤依次讲解:

  1. 轮播图的基本结构搭建及原理分析
  2. 光标移动至轮播图处切换按钮的显示与隐藏
  3. 点击下方按钮切换图片的实现
  4. 右侧按钮滚动实现 以及 下方点点同步改变
  5. 左侧按钮滚动实现 以及 下方点点同步改变
  6. 自动播放实现

一: 轮播图的基本结构搭建及原理分析

其实轮播图的构成很简单,仅由显示区域和图片区域两部分组成,图片区域由一个 ul 标签实现,内部一个 li 标签里放一张图片,使其左浮动形成一行,其移动其实靠的就是 ul 的 动画原理 左右移动来改变显示区域,效果如下:(页面结构的HTML与CSS,还有封装好的动画函数js文件在文章末尾)


二: 光标移动至轮播图处切换按钮的显示与隐藏

光标移动到轮播图区域使左右切换图片按钮显示与隐藏,我们用到两个事件分为: mouseenter 和 mouseleave,之所以不用 mouseover 和 mouseout 是因为这两个事件会冒泡,会产生很多不可控的影响,但两组事件的效果几乎完全相同。绑定事件后改变按钮的 display 值即可。

首先我们先了解一下获取到的元素有哪些,以免下面的分步讲解有疑惑的地方:

    var leftbtn=document.querySelector('.leftbtn');   //左按钮var rightbtn=document.querySelector('.rightbtn');  //右按钮var windows=document.querySelector('.windows');  //显示窗口区域var circleul=document.querySelector('.imgbox');  //装图片的 ulvar circleol=document.querySelector('.circle');  //装下方小点点的 ol

此部分是 光标移动至轮播图处切换按钮的显示与隐藏 的实现:

  windows.addEventListener('mouseenter',function(){leftbtn.style.display='block';rightbtn.style.display='block';clearInterval(timer)    //清除定时器自动播放,此处不需要管timer=null;})windows.addEventListener('mouseleave',function(){leftbtn.style.display='none'rightbtn.style.display='none'timer=setInterval(function(){rightbtn.click();},2000)})leftbtn.addEventListener('click',function(){  //按钮点击后变色一下的效果leftbtn.style.color='grey'var timer=setTimeout(function(){leftbtn.style.color='aliceblue'},100)})rightbtn.addEventListener('click',function(){rightbtn.style.color='grey'var timer=setTimeout(function(){rightbtn.style.color='aliceblue'},100)})

三:点击下方按钮切换图片的实现

for循环的作用为根据 ul 中图片的个数来添加 ol 中小点点的个数并添加在 ol 中,给创建的 li 添加自定义属性 indexfor 循环的 i 作为其每个 li 的属性值,而图片作为ul的子节点,分别对应 children[0],children[1],children[2],children[3],正好与自定义属性的 index 一一对应,也就是说每个点点都配对一个同样序号的图片。

在添加每个 li 的同时就给每个 li 绑定点击事件,并获取该自定义属性index,使用 排他思想 更改点击的原点的颜色,并调用封装好的动画函数就可以完成点击小圆点切换图片的效果

 这两行是移动的关键代码:windows.offsetWidt 作用是获取每张图片的宽度,-6 是为了消除一些移动中由于图片与图片之间间隔产生的误差

var imgwidth=windows.offsetWidth-6;
var long=this.getAttribute('index')*imgwidth;

点第一个小点点:

 点第二个小点点:

 点第三个小点点:

代码实现:

 for(var i=0;i<circleul.children.length;i++){   //根据图片个数自动创建小点点个数lis=document.createElement('li');lis.setAttribute('index',i);circleol.appendChild(lis);lis.addEventListener('click',function(){var currentindex=this.getAttribute('index'); //bug整改num=currentindex;  //bug整改circlechange=currentindex;  //bug整改for(var i=0;i<circleol.children.length;i++){  //排他思想circleol.children[i].className='';}this.className='circlecolor';var imgwidth=windows.offsetWidth-6;var long=this.getAttribute('index')*imgwidth;run(circleul,-long);  //封装好的动画函数})}

四:右侧按钮滚动实现 以及 下方点点同步改变

总算到了关键的一步,通过按钮来使轮播图运动,也是本案例最抽象的一部分,抽象在它最后一张和第一张的无缝衔接,此处要说明我们要使其无缝衔接的原理,是将第一张图片克隆一份放在最后一张图片的后面(下方点点数不包括克隆的这一张图片,但是ul 的子元素包含了这个新克隆的图片!),在图片滚动到该克隆图片后,立马将其 ul 的 left 值改为 0 。

克隆第一张图片我们使用节点的带参克隆 :

var firstimg=circleul.children[0].cloneNode(true);
circleul.appendChild(firstimg);

我们已经知道了图片滚动的距离等于该图片的顺序乘图片宽度,在这里我们先设置一个全局变量num,并设初始值为0,点击一次右侧按钮则 num 自增1,第一次点击 num自增1, num=1,移动距离为 1✖宽度,第二次点击 num 自增 1,num=2,移动距离为 2✖宽度,前面几步都好理解,但是当num 为最后无缝衔接时需要一个判断语句,我们重点研究无缝衔接的原理:

第一次点击右侧按钮后:

第二次点击右侧按钮后:

第三次点击右侧按钮后:

第四次点击右侧按钮后:

注意此步骤判断前 num=3,即不执行判断里的语句,但是判断完后num自增为4,也就是说下一次就要执行判断里的语句

第五次点击右侧按钮后:

为什么点击后直接到了第二张图片呢?不是在判断语句里设置了left为0吗?这是因为判断中设置了num=0和left=0后才自增1,所以这一次点击后带入动画函数的num=1,移动距离为1✖宽度,又开始新一轮循环图片!

代码实现:

    num=0;circlechange=0;  //目的为下方点点同步改变时使用,这一步先不用管这个参数rightbtn.addEventListener('click',function(){if(num==circleul.children.length-1){circleul.style.left=0;num=0;}num++;long=num*windows.offsetWidth-6*num;run(circleul,-long);

我们点击右侧按钮,图片滚动的同时,小圆圈也应该跟着切换才对,该怎么实现呢?

每点击一次都让circlechange这个变量自增,当自增到值和 circleul.children.length-1 的值相等时(即滚动到了克隆过去的最后一张图片),这时让 circlechange 变为 0 即可

  circlechange++;if(circlechange==circleul.children.length-1){circlechange=0;}for(var i=0;i<circleol.children.length;i++){  //排他思想circleol.children[i].className='';}circleol.children[circlechange].className='circlecolor';})

五:左侧按钮滚动实现 以及 下方点点同步改变

向左切换和向右切换的原理类似,在此我们只研究第一张图片开始往左无缝衔接最后一张图片的过程

第一次点击左侧按钮后:

代码实现: 

 leftbtn.addEventListener('click',function(){if(num==0){circleul.style.left=(circleul.children.length-1)*windows.offsetWidth;num=circleul.children.length-1;}num--;long=num*windows.offsetWidth-6*num;run(circleul,-long);

 点击左侧按钮,小圆圈跟随切换:

 circlechange--;if(circlechange<0){circlechange=circleol.children.length-1;  //注意此处是ol的子节点的长度-1}for(var i=0;i<circleol.children.length;i++){circleol.children[i].className='';}circleol.children[circlechange].className='circlecolor';})

六:自动播放实现

自动播放最简单!,只需要一个自动点击即可

此处为右侧按钮自动点击:rightbtn.click()

将其添加在定时器中就可以完成我们的轮播图啦

 var timer=setInterval(function(){rightbtn.click();},2000)

完整JS代码:

我们的 JS 是单独的一个文件,所以加入了 load 事件等文档流执行完毕后,再执行 JS 的内容

window.addEventListener('load',function(){var leftbtn=document.querySelector('.leftbtn');var rightbtn=document.querySelector('.rightbtn');var windows=document.querySelector('.windows');var circleul=document.querySelector('.imgbox');var circleol=document.querySelector('.circle');//光标移动至轮播图区域按钮显示,移开隐藏,点击按钮的变化效果windows.addEventListener('mouseenter',function(){leftbtn.style.display='block';rightbtn.style.display='block';clearInterval(timer)//清除定时器自动播放timer=null;})windows.addEventListener('mouseleave',function(){leftbtn.style.display='none'rightbtn.style.display='none'timer=setInterval(function(){rightbtn.click();},2000)})leftbtn.addEventListener('click',function(){leftbtn.style.color='grey'var timer=setTimeout(function(){leftbtn.style.color='aliceblue'},100)})rightbtn.addEventListener('click',function(){rightbtn.style.color='grey'var timer=setTimeout(function(){rightbtn.style.color='aliceblue'},100)})//点击小圆圈可以滚动for(var i=0;i<circleul.children.length;i++){lis=document.createElement('li');lis.setAttribute('index',i);circleol.appendChild(lis);lis.addEventListener('click',function(){var currentindex=this.getAttribute('index');//bug整改(3行)num=currentindex;circlechange=currentindex;for(var i=0;i<circleol.children.length;i++){circleol.children[i].className='';}this.className='circlecolor';var imgwidth=windows.offsetWidth-6;var long=this.getAttribute('index')*imgwidth;run(circleul,-long);})}circleol.children[0].className='circlecolor';//克隆第一张图片至末尾var firstimg=circleul.children[0].cloneNode(true);circleul.appendChild(firstimg);//右侧按钮点击滚动num=0;circlechange=0;rightbtn.addEventListener('click',function(){if(num==circleul.children.length-1){circleul.style.left=0;num=0;}num++;long=num*windows.offsetWidth-6*num;run(circleul,-long);//小圆圈跟着一起变化circlechange++;if(circlechange==circleul.children.length-1){circlechange=0;}for(var i=0;i<circleol.children.length;i++){circleol.children[i].className='';}circleol.children[circlechange].className='circlecolor';})//左侧按钮滚动leftbtn.addEventListener('click',function(){if(num==0){circleul.style.left=(circleul.children.length-1)*windows.offsetWidth;num=circleul.children.length-1;}num--;long=num*windows.offsetWidth-6*num;run(circleul,-long);//小圆圈跟着一起变化circlechange--;if(circlechange<0){circlechange=circleol.children.length-1;  //注意此处是ol的子节点的长度-1}for(var i=0;i<circleol.children.length;i++){circleol.children[i].className='';}circleol.children[circlechange].className='circlecolor';})//自动播放var timer=setInterval(function(){rightbtn.click();},2000)})

动画函数代码:

function run(obj,long,callback){clearInterval(obj.timer)obj.timer=setInterval(function(){if(obj.offsetLeft==long){window.clearInterval(obj.timer);if(callback){callback();}}else{step=(long-obj.offsetLeft)/10step=step>0?Math.ceil(step):Math.floor(step)obj.style.left=obj.offsetLeft+step+'px';}},20)}

HTML+CSS 完整代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>*{margin: 0;padding: 0;}.windows{position: relative;border: 3px rgb(146, 146, 146) solid;width: 700px;height: 450px;background-color: rgb(250, 186, 186);margin: 170px auto;overflow: hidden;}.leftbtn{z-index: 999;position: absolute;box-sizing: border-box;top: 195px;left: 0;width: 50px;height: 70px;background-color: rgba(136, 135, 135, 0.582);line-height: 70px;text-align: center;font-size: 35px;color: rgba(255, 255, 255, 0.609);cursor: pointer;display: none;}.leftbtn:hover{background-color: rgba(189, 186, 186, 0.623);color: aliceblue;}.rightbtn{z-index: 999;position: absolute;box-sizing: border-box;top: 195px;right: 0;width: 50px;height: 70px;background-color: rgba(136, 135, 135, 0.609);line-height: 70px;text-align: center;font-size: 35px;color: rgba(255, 255, 255, 0.596);cursor: pointer;display: none;}.rightbtn:hover{background-color: rgba(189, 186, 186, 0.623);color: aliceblue;}.imgbox{position:absolute;left: 0;top: 0;box-sizing: border-box;width: 700%;height: 450px;}.imgbox li{float: left;box-sizing: border-box;width: 700px;height: 450px;list-style: none;}.imgbox li a{box-sizing: border-box;display: inline-block;width: 700px;height: 450px;background-color: rgb(134, 152, 255);}.imgbox li a img{cursor:auto;width: 700px;height: 450px;}.circlebox{position: absolute;bottom: 0;width: 700px;height: 40px;background-color: rgba(94, 94, 94, 0.486);}.circle {position: absolute;bottom: 10px;left: 300px;}.circle li {float: left;width: 7px;height: 7px;list-style: none;border: 2px solid rgb(185, 185, 185);border-radius:100%;margin: 3px;cursor: pointer;background-color: rgb(173, 173, 173);}.circlecolor{background-color: coral !important;border: 2px solid coral !important;}</style><script src="../js/run.js"></script><script src="../js/btn-display.js"></script>
</head>
<body><div class="windows"><div class="leftbtn"> < </div><div class="rightbtn"> > </div><ul class="imgbox"><li><a href="#"><img src="../轮播photo/1.jpg" alt="轮播图" class="lunboimg"></a></li><li><a href="#"><img src="../轮播photo/2.jpg" alt="轮播图" class="lunboimg"></a></li><li><a href="#"><img src="../轮播photo/3.jpg" alt="轮播图" class="lunboimg"></a></li><li><a href="#"><img src="../轮播photo/4.jpg" alt="轮播图" class="lunboimg"></a></li><li><a href="#"><img src="../轮播photo/5.jpg" alt="轮播图" class="lunboimg"></a></li><li><a href="#"><img src="../轮播photo/6.jpg" alt="轮播图" class="lunboimg"></a></li></ul><div class="circlebox"><ol class="circle"></ol></div></div>
</body>
</html>

【学会轮播图这一篇文章就足够啦】JS 网页轮播图详解 自动播放+手动播放相关推荐

  1. 一篇文章教会你使用html+css3制作GIF图

    简介:一篇文章教会你使用html+css3制作GIF图 [一.项目背景] 生活中经常会见到很多gif图,那么gif图到底是什么?GIF是一种位图.简单来说就是通过每一张张静图,通过控制它的关键帧,从而 ...

  2. 一篇文章彻底说清JS的深拷贝/浅拷贝

    一篇文章彻底说清JS的深拷贝and浅拷贝 这篇文章的受众 第一类,业务需要,急需知道如何深拷贝JS对象的开发者. 第二类,希望扎实JS基础,将来好去面试官前秀操作的好学者. 写给第一类读者 你只需要一 ...

  3. layui的轮播图片自适应大小_如何使用LayUI实现网页轮播图

    详细内容 本篇文章介绍了使用LayUI实现网页轮播图的方法,具有一定的参考价值,希望对学习Layui的朋友有帮助!想要用layui写出来轮播图,需要先下载layui的文档,下载到电脑上就可以了,随便保 ...

  4. 轮播图实现html,html、css、js实现轮播图

    2017-03-13 今天把轮播图的知识1过了一下,写了一个比较简单的轮播图,给大家参考一下. 查看具体的效果点击这个链接 : http://gjhnstxu.me/%E8%BD%AE%E6%92%A ...

  5. vue获取div中的值_一篇文章看懂Vue.js的11种传值通信方式

    面试的时候,也算是常考的一道题目了,而且,在日常的开发中,对于组件的封装,尤其是在 ui组件库中,会用到很多,下面,就来详细的了解下,通过这篇文章的学习,可以提升项目中组件封装的灵活性,可维护性,话不 ...

  6. Numpy用法详细总结:学习numpy如何使用,看这一篇文章就足够了

    Numpy用法详细总结 一.创建ndarray及查看数据类型 1. 使用np.array()由python list创建 图片与array数组的关系 2. 使用np的常用函数创建 二.ndarray的 ...

  7. base64 转二进制_一篇文章弄明白Node.js与二进制数据流

    1 认识二进制数据 二进制是计算技术中广泛采用的一种数制.二进制数据是用0和1两个数码来表示的数.它的基数为2,进位规则是"逢二进一",借位规则是"借一当二", ...

  8. 二进制差分码规则_一篇文章弄明白Node.js与二进制数据流

    1 认识二进制数据 二进制是计算技术中广泛采用的一种数制.二进制数据是用0和1两个数码来表示的数.它的基数为2,进位规则是"逢二进一",借位规则是"借一当二", ...

  9. selenium爬虫如何绕过反爬,看这一篇文章就足够了

    文章目录 关闭/开启WebRTC 背景 什么是WebRTC 解决方案 python版本加上代理(不关闭webrtc) python版本加上代理(关闭webrtc) 伪装浏览器时区和地理位置 原因 解决 ...

最新文章

  1. C++调用matlab char16_t 重复定义
  2. 人本质要好,要善良,要真诚,有格局和胸怀,有能力,有眼光,能讲故事,能找到人,能搞到钱...
  3. 【leetcode】Balanced Binary Tree(middle)
  4. 模式识别中Fisher分类器的Matlab实现及测试
  5. linux centos6.5 ftp网页vsftpd配置
  6. java插入数据库字符串拼接_JAVA字符串怎么连接?
  7. 高等数学下-赵立军-北京大学出版社-题解-练习9.3
  8. 手机版wps怎么制作折线图_手机怎么制作电子签名?有没有手机电子签名软件或者APP?...
  9. xe DateTimePicker.Date bug
  10. 国庆长假前不妨先来做完这份 JavaScript 测验吧!因为......
  11. Linux 昨天时间
  12. DropDownList操作;ListBox操作;动态创建控件;Response.Write(欢迎学习ASP.NET''!);
  13. 想做影视“化妆师”,首先要知道影视后期调色的8个基本步骤!
  14. Windows官方经典壁纸
  15. 两英中学2021高考成绩查询,2021年广东高中排名,高中高考成绩排名一览表
  16. JavaPoet使用详解
  17. SI512国产13.56MHz低功耗NFC前端芯片替代PN532/PN512
  18. SpringBoot中shiro 添加sessionManager和cacheManager
  19. 昆明拟整治11类陋习 行人翻越隔离设施罚50元
  20. 现在智能机怎么玩Java游戏,教你如何用安卓机玩JAVA老游戏

热门文章

  1. 创建反向词典,为你打开神经网络的大门
  2. Cesium不改源码支持坐标系为4490的ArcGIS Rest缓存服务的解决方案,代码为TypeScript编写(vx gzh【图说GIS】)
  3. vSAN 6.6在线研讨会-4月20日下午2:30 amp;amp; 小提示:如何理解FTT与纠删码的组合?
  4. 新计算机的windows要不要不断更新,win10一直出现无法完成更新正在撤销更改请不要关闭你的计算机,怎么办?...
  5. 天气变冷了,用Python给爸妈制作一个天气提醒小助手
  6. Aptana Studio3汉化方式
  7. 智能化运维最佳实践-自动化
  8. wps连接mysql odbc_如何在WPS中使用ADO连接数据库?
  9. ThingJS 3D场景层级切换,体验不一样的动感!
  10. 记一次基于vmware的gentoo安装