纯原生js实现简单可控轮播图
先说一下实现思路,定义一个相框里面存取着一个具有overflow属性的ul列表,ul列表中存放着若干图片,定义动画来促使照片移动,移动的距离是相框的宽度(imgWidth)*照片索引值(index)
这里到达最后一张图片要切换到第一张的时候,有一个技巧
就是复制第1张图片的DOM元素并添加到ul列表的最后,例如现在我们有6张图片,当轮播到第6张的时候,那么下一张就是第1张,但当我们添加多一个元素后,实际上显示的是第7张图片,所以这里要加判断如果是第7张图片,就要把索引重置成为第1张图片,即索引值为0
html结构
<div class="box" id="box">
<div class="inner"><!--相框-->
<ul>
<li><a href="#"><img src="image1" /></a></li>
<li><a href="#"><img src="image2" /></a></li>
<li><a href="#"><img src="image3" /></a></li>
<li><a href="#"><img src="image4" /></a></li>
<li><a href="#"><img src="image5" /></a></li>
<li><a href="#"><img src="image6" /></a></li>
</ul>
<div class="square">
/*定义默认样式current*/
<span class="current">1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
</div>
/*定义左右控件*/
<div id="focus" style="display: none">
<span id="left"><</span><span id="right">></span>
</div>
</div>
</div>
原生js代码
//获取最外面的div
let box = document.getElementById("box");
//获取相框
let inner = box.children[0];
//获取相框的宽度
let imgWidth = inner.offsetWidth;
//获取ul
let ulObj=inner.children[0];
//获取所有的span标签
let spanObjs=inner.children[1].children;
let index = 0;
//循环遍历所有的span标签,注册鼠标进入的事件
for(let i=0; i < spanObjs.length; i++){
//循环的时候把索引值保存在每个span的自定义属性中
spanObjs[i].setAttribute("index", i);
//注册鼠标进入事件
spanObjs[i].onmouseover = function () {
//先干掉所有的span的背景颜色
for(let j=0; j < spanObjs.length; j++){
//移除了每个span的类样式
spanObjs[j].removeAttribute("class");
}
//设置当前的span的背景颜色
this.className = "current";
//移动ul(每个图片的宽*鼠标放在这个按钮的索引值)
//获取当前鼠标进入的span的索引
index = this.getAttribute("index");
animate(ulObj, -index*imgWidth);
};
}
//添加第1张图片到ul列表的最后
ulObj.appendChild(ulObj.children[0].cloneNode(true));
//自动播放
let timeId = setInterval(clickHandle,2000);
//为box注册鼠标进入,鼠标离开的事件,
//进入时显示控件并停止自动轮播,离开时继续自动播放
box.onmouseover = function(){
document.getElementById('focus').style.display = "block";
clearInterval(timeId);
};
box.onmouseout = function(){
document.getElementById('focus').style.display = "none";
timeId = setInterval(clickHandle,2000);
};
//左右焦点按钮
document.getElementById('right').onclick = clickHandle;
function clickHandle(){
//当是最后一张时,要把图片重置回第一张,同时将ul列表移动置最开始的位置,以便接下来轮播第2张
if(index == ulObj.children.length - 1){
index = 0;
ulObj.style.left = 0+'px';
}
//如果不是最后一张,那就++
index++;
//根据索引值移动ul
animate(ulObj,-index*imgWidth);
//如果index=6,显示的是第七张图片,用户看来是第一张(第一个小按钮有样式)
if(index == ulObj.children.length - 1){
spanObjs[0].className = 'current';
spanObjs[spanObjs.length-1].className = '';
}else{
for(let j=0;j < spanObjs.length;j++){
//移除了每个span的类样式
spanObjs[j].removeAttribute("class");
}
//设置当前的span的背景颜色
spanObjs[index].className = 'current';
}
};
//左边按钮
document.getElementById('left').onclick = function(){
//当是第一张图片时点击左控件应当是跳到最后1张
//此时这里最后一张还是我们第一张图片,即上面添加的DOM元素,就是为了平缓过渡到真实的最后1张图
if(index == 0){
index=ulObj.children.length-1;
//先转移到虚拟上的最后1张
ulObj.style.left = -index * imgWidth + "px";
}
//再-- 平缓过渡到实际上的最后一张图
index --;
animate(ulObj,-index*imgWidth);
for(let j=0; j < spanObjs.length; j++){
//移除了每个span的类样式
spanObjs[j].removeAttribute("class");
}
//设置当前的span的背景颜色
spanObjs[index].className = 'current';
};
//设置任意的一个元素,移动到指定的目标位置
function animate(element, target) {
//点击一次就清除一次定时器,这里是为了解决多次点击之后速度更变的问题。
clearInterval(element.timeId);
//定时器的id值存储到对象的一个属性中
element.timeId = setInterval(function () {
//获取元素的当前的位置,数字类型
var current = element.offsetLeft;
//每次移动的距离
var step = 50;
step = current < target ? step : -step;
//当前移动到位置
current += step;
if (Math.abs(current - target) > Math.abs(step)) {
element.style.left = current + "px";
} else {
//清理定时器
clearInterval(element.timeId);
//直接到达目标
element.style.left = target + "px";
}
}, 15);
}
最后是css样式,大家直接复制就ok,都是很简单的一些样式
* {
margin: 0;
padding: 0
}
ul {
list-style: none
}
img {
vertical-align: top;
width: 730px;
height: 454px;
}
.box {
width: 730px;
height: 454px;
margin: 100px auto;
padding: 5px;
border: 1px solid #ccc;
}
.inner {
width: 730px;
height: 454px;
overflow: hidden;
position: relative;
}
.inner ul {
width: 1000%;
position: absolute;
top: 0;
left: 0;
}
.inner li {
float: left;
}
.square {
position: absolute;
right: 10px;
bottom: 10px;
}
.square span {
display: inline-block;
width: 16px;
height: 16px;
background-color: #fff;
text-align: center;
line-height: 16px;
cursor: pointer;
}
.square span.current {
background-color: orangered;
color: #fff;
}
#focus span{
background-color: rgba(0,0,0,0.3);
color:white;
font-size:40px;
text-align: center;
width: 40px;
height: 70px;
line-height: 60px;
position: absolute;
top: 50%;
margin-top: -35px;
cursor:pointer;
}
#left{
float: left;
}
#focus #right{
float:right;
right: 0;
}
看懂记得点个小赞哦,纯手写,献上小弟的膝盖!!