展示界面 & github源码

- github源码(包含两种方式实现轮播图的源码)
前言
- 这段时间在学习切页面的时候,发现页面上的轮播图部分让我很感兴趣,因为是刚开始学习javascript,所以想要自己手写一个轮播图,于是查阅了好多资料,发现写轮播图的方法很多很杂,虽然最终学会了如何使用js写轮播图,但是花了我好长时间。
- 现在我想把自己总结的方法分享出来,其中第二种方法我个人觉得还是比较有价值的,在网上没有搜到类似的文章,希望给以后想写轮播图的小伙伴一点思路。
需求分析
- 循环无缝自动轮播四张图。
- 可以手动左右切换图片(后面我会有两种手动切换图片的方式来切换图片)。
- 鼠标点击(触及)轮播图下面的小点可以跳转到对应的图片。
看看第一种方法写的轮播图的效果:

(这种方法移动到图片上会停止滚动,显示按钮,离开又开始滚动,隐藏按钮。)
实现原理

- 首先理解该轮播图如何滚动,通过控制包含所有图片的父容器的left值来显示图片,在这个容器中只有和视图容器重叠的部分会显示出来,其他的都被隐藏了。
- 为了实现“滚动”的效果,我们需要逐渐改变包含所有图片的父容器的left值,而不能直接使该值变化图片宽度的倍数。下面我们会定义一个动画效果函数Roll(),这里可以先不用管。
实现过程 & 思路
第一种轮播方式比较常见,这里我就拎重点讲,再详细讲一下js部分.CSS和HTML代码请到github源码中查看.
HTML部分
- 这里用了三个盒子,最外层id为parent的大盒子内包含了uls和buttons两个盒子,盒子uls中包含了两个列表img_ul(图片列表)和litCir_ul(小圆点列表),盒子buttons里则包含了“左”,“右”两个按钮。
CSS部分
- 这里css需要注意的是uls设置了overflow: hidden;所以它的子容器img_ul只会显示和uls盒子重叠的部分,其他部分隐藏;
- 给img_ul设置宽度要长多出一张图片的宽度,用以放后面克隆的图片(js部分会详细讲);
JS部分
// 这里我们先添加小圆点,让页面显示完整,之所用js添加小圆点,
是因为小圆点的数量应该由图片张数决定的。
for(let i = 0; i < len;i++){
var a_li = document.createElement('li');//创建li元素节点
a_li.className = 'quiet';//给li添加类名quiet
litCir_ul.appendChild(a_li);
}
- 将会在下面用到的Html中的对象和一些变量
/*获取HTML中的对象*/
var parent = document.getElementById("parent");
var img_ul = document.getElementById("img_ul");
var litCir_ul = document.getElementById("litCir_ul");
var buttons = document.getElementById("buttons");
var cLis =litCir_ul.children; //children 属性返回元素的子元素的集合
//定义一些变量
var len = img_ul.children.length; //图片张数
var width = parent.offsetWidth; //每张图片的宽度
var rate = 15; //一张图片的切换速度, 单位为px
var times = 1; //切换速度的倍率
var gap = 2000; //自动切换间隙, 单位为毫秒
var timer = null; //初始化一个定时器
var picN = 0; //当前显示的图片下标
var cirN = 0; //当前显示图片的小圆点下标
var temp;
- 首先理解无缝滚动是怎么做到的,这里定义一个动画效果函数Roll();通过传进来的distance来控制img_ul的位置来显示,设置img_ul的left值,以达到图片滚动的.
function Roll(distance){ //参数distance:滚动的目标点(必为图片宽度的倍数)
clearInterval(img_ul.timer); //每次运行该函数必须清除之前的定时器!
var speed = img_ul.offsetLeft < distance ? rate : (0-rate); //判断图片移动的方向 此处用了三元运算符 ? 前面的不等式成立时为rate,不成立时为0-rete
// console.log(speed)
img_ul.timer = setInterval(function(){ //设置定时器,每隔10毫秒,调用一次该匿名函数
img_ul.style.left = img_ul.offsetLeft + speed + "px"; //每一次调用滚动到的地方 (速度为 speed px/10 ms) offsetLeft为元素边框外侧到父元素边框内侧的距离
var leave = distance - img_ul.offsetLeft; //距目标点剩余的px值
/*接近目标点时的处理,滚动接近目标时直接到达, 避免rate值设置不当时不能完整显示图片*/
if (Math.abs(leave) <= Math.abs(speed)) {
clearInterval(img_ul.timer);
img_ul.style.left = distance + "px";
}
},10);
}
- 当图片从最后一张切换到第一张时,这时就不能通过逐渐改变img_ul的left值来实现滚动的效果,于是克隆第一张图片至列表尾部,当滚动完最后一张图片时,继续滚动到克隆的第一张,然后将img_ul的left值重置为0。
img_ul.appendChild(img_ul.children[0].cloneNode(true));//克隆第一张图片至列表尾部
- 定义自动滚动函数autoRun()
function autoRun(){
picN++
cirN++
//如果轮播完克隆项应该轮播回第二张照片上,因为克隆项和第一张图片一样
if(picN > len) {
img_ul.style.left = 0;//改变left至真正的第一项处,这个过程是时间太快太短所以可以忽略不计然后立刻
picN = 1; //从第二张开始显示
}
// 自动轮播,当图片为第一张时应该自动到第二张上去,所以要传入第二张的picN值,依次类推
Roll(-picN*width)
//判断是否到了最后一个圆点,当圆点到了最后一个时,应该变回第一个点进行轮播
if (cirN > len - 1) {
cirN = 0;
}
for(var i = 0; i < len;i++) {
cLis[i].className = 'quiet';//让所有圆点背景色变为默认色
}
cLis[cirN].className = 'active';
}
- 注意:以上轮播图片时是当图片索引值picN已经有了,要+1,等待一定时间执行移动到下一张图片的事件
开始自动滚动: timer = setInterval(autoRun, gap); //定时器 - 给小圆点设置触及事件
for(let j = 0;j < len ;j++){ cLis[j].index = j;//给每个圆点一个索引值 cLis[j].onmouseover = function() { for(var k = 0; k < len;k++) { cLis[k].className = 'quiet';//让所有圆点背景色变为默认色 } this.className = 'active'; temp = cirN; picN = cirN = this.index; times = Math.abs(this.index - temp);//距离上个小圆点的距离 rate = rate*times;//根据距离改变切换速率 Roll(-this.index * width); rate = 15; } } - 接下来是触及轮播图区域,图片停止轮播,显示左右按钮,离开该区域时,又重新开始定时器的自动轮播,左右按钮隐藏.
//触及轮播图区域,清除定时器 parent.onmouseover = function(){ clearInterval(timer); buttons.style.display = 'block'; }//离开该区域时,重新开始定时器的自动轮播 parent.onmouseout = function(){ buttons.style.display = 'none'; timer = setInterval(autoRun, gap); } - 下面是设置左右按钮点击切换图片的事件.
//给左边按钮添加点击事件 buttons.children[0].onclick = function() { picN--; cirN--; if(picN < 0){ img_ul.style.left = -len*width + 'px'; picN = len - 1; } Roll(-picN*width); if(cirN < 0){ cirN = len - 1; } for(var i = 0; i < len; i++) { cLis[i].className = 'quiet'; } cLis[cirN].className = 'active'; } //给右边按钮添加点击事件 buttons.children[1].onclick = autoRun; //自动播放就是间隔一定时间不断调用函数“下一张”的过程,所以这里的 按钮right下一张的实现就是上面的autoRun函数。
总结
本来想写两种方式实现轮播图的,由于第一次在掘金社区里写文章,没有控制好字数,感觉写的太长太多了,所以这里先写第一种原生js方式的实现轮播图。如果想了解第二种原生js是如何实现轮播图的话,我会继续更新的哦!请持续关注,这也是笔者的第一篇文章,如果各位看官喜欢请点赞收藏,这对笔者是莫大的鼓励😊。