原生Js实现轮播图
文章目录
前言
最近决心重新学习一次js,打牢基础,先从最常见的轮播图开始。
一、轮播图是什么?
顾名思义,就是轮流播放的图片,多应用在电商平台的海报,当我们进入一个网页中,轮播图一般是是最醒目的。
二、Html+Css
因为我们主要是实现滚动的功能,html和css就简单的说一下,轮播图一般包括三块内容,轮播的海报,海报两边的箭头,底部的圆圈。如下图:
1.html结构
轮播的图片可以放在ul列表当中,两侧的箭头用a标签,底部的圆圈用ol列表,放到一个 div标签中。
箭头和圆圈是通过雪碧图引入。
<div class="slideshow">
<ul>
<li><a href="#"><img src="./img/1.jpg" alt=""></a></li>
//...
</ul>
<div class="nav">
<ol class="circle">
//ol 中的li使用js动态生成,这样便于后期的维护
</ol>
<a href="javascript:;" class="left"></a>
<a href="javascript:;" class="right"></a>
</div>
</div>
2.css
轮播图一定不止一张,我们可以观察到轮播图变化的时候,方向是左右变换,因此我们就需要将所有图片放到一行上面,这时候只需要改变父容器的宽度就可以。
.slideshow ul{
position: absolute;
width: 600%;
height: 100%; // 可以省略
}
为了方便定位圆圈以及箭头的位置,我们可以先在htmll中写上 li标签,等定位好以后在删除。剩下的就是雪碧图的应用了
三、 Js
1.做出鼠标移动到轮播图区域中箭头显示的效果
要实现这一效果,只需要将对应选择器的样式从 display:block
改为 display:none就可以,要复原的话,当鼠标离开区域的时候在将属性改回来就行。有1个知识点需要注意:
- 在进行事件绑定,鼠标移入:mouseenter 鼠标移除:mouseleave
window.addEventListener("load", function(){
// load 目的是为了让页面加载完成之后,在加载js
var left = document.querySelector('.left');
var right = document.querySelector('.right');
var slideshow = document.querySelector('.slideshow');
//slideshow 是整个轮播图的父容器
slideshow.addEventListener('mouseenter', function(){
left.style.display = 'block';
right.style.display = 'block';
})
slideshow.addEventListener('mouseleave', function(){
left.style.display = 'none';
right.style.display = 'none';
})
})
2.动态生成圆圈
要动态生成圆圈,必须要和图片的数量进行绑定,就要获取ul标签,通过ul.children.length来得到圆圈的数量
var ul = document.querySelector('ul');
var ol = document.querySelector('.circle');
for(var i = 0; i < ul.children.length;i++){
//创建li
var li = document.createElement('li');
//将li插入到 ol 当中
ol.appendChild(li);
//给 第一个 li 绑定样式
ol.children[0].className = 'current';
}
3.点击箭头让图片动起来
要让图片向左动起来,就必须要写一个动画函数实现这一功能,这一函数放到最后名字叫做 animate
每次要移动一整张图片,图片的宽度一般就是整个区域的宽度,我们可以获取区域的宽度进行移动。
图片向右动起来,原理相同
// offsetWidth 水平方向 width + 左右padding + 左右border-width
// offsetHeight 垂直方向 height + 上下padding + 上下border-width
var slideshowWidth = slideshow.offsetWidth;
var num = 0;
right.addEventListener('click', function(){
//当最后一张图片播放完之后,另num = 0;从第一张开始播放
if(num == ul.children.length - 1){
//注意:在返回第一张图片的时候,不仅num要变成0,ul的定位也要变成0,第一张图片。
//否则:图片会从 第四张,第三张,第二张,一直往回倒,看起来很不自然
ul.style.left = '0px';
num = 0;
}
// 鼠标点击一次,num + 1
num ++;
//调用animate函数
animate(ul, - num * slideshowWidth);
})
但是我们可以注意到一个问题,当最后一张图片播放之后会出现一个空白期,再次点击后会直接跳到第二张图片,看起来不舒服,因此我们可以将第一张图片复制一下放到四张图片的后面,而这张图片的li不能在圆圈之前创建,否则元圆圈的数量会多出来一个。
//复制第一张图片
//注意:克隆第一张图片的时候,一定要将后代一起克隆,只复制 li 是没用的,我们要的是 其中的 img
var first = ul.children[0].cloneNode(true);
ul.appendChild(first);
4.实现点击圆圈的时候图片变换
这部分代码放在第二步的for循环中,这一步其实在第二步之后更为方便。
点击圆圈图片变换,本质也是调用了animate函数,因此为了计算移动的距离,必须要定义圆圈的索引。此时用到了setAttribute()方法,添加指定的属性并为其赋指定的值
//圆圈的索引 index
li.setAttribute('index',i);
//排他思想
li.addEventListener('click',function(){
//干掉所有人
for(var i=0;i < ol.children.length;i++){
ol.children[i].className = '';
}
//留下我自己
this.className = 'current';
//点击圆圈,移动图片 移动距离 索引 * 宽度
var index = this.getAttribute('index');
animate(ul, - index * slideshowWidth);
5.解决点击箭头时,图片与圆圈不匹配的问题
同样是排他思想,可以定义一个方法,在箭头事件中进行调用
注意:先 ++/–,在判断,和先判断在++/–有细微的差别。
function circleChange(){
for(var i = 0; i < ul.children.length;i ++){
ol.children[i].className = '';
ol.children[circle].className = 'current';
}
}
//右侧箭头
circle ++;
if(circle == ol.children.length){
circle = 0;
}
circleChange();
//左侧箭头
circle --;
if(circle < 0){
circle = ol.children.length - 1;
}
circleChange();
再全局定义一个circle变量。
6.自动播放功能
自动播放功能相当于手动点击右箭头的点击事件
var timer = setInterval(function(){
//手动调用点击事件
right.click();
},2000)
鼠标移入停止自动播放,因为之前写过鼠标移入移出事件,所以直接将代码加入到其中就行
//删除定时器
clearInterval(timer);
timer = null; //清除定时器
鼠标移出继续开始
// timer 之前不能加 var 否则当鼠标移出之后会图片会加速
timer = setInterval(function(){
//手动调用点击事件
right.click();
},2000)
end:animate动画函数
function animate(obj,target,callback){
// obj 是移动的对象 target 移动的距离 callback 回调函数
clearInterval(obj.timer); //清除定时器,放在重复调用
obj.timer = setInterval(function(){
// 步长值取整 向上取整 Math.ceil
// var step = Math.ceil((target - obj.offsetLeft)/ 10);
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if(obj.offsetLeft == target){
clearInterval(obj.timer);
if(callback){
callback();
}
}
obj.style.left = obj.offsetLeft + step + 'px';
},20)
}
总结
Js轮播图的学习,学习到了setIntervalclearInterval定时器的使用,offsetWidth的用法等另思维更加清晰,对之前学习的基础语法进行了巩固。