原生js实现轮播图效果
最近大致学完了js的几个大的部件,跟着老师上手做了这个简单的轮播,即使只有一个粉丝,我要坚持走下去!
下面是代码<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>轮播图</title>
<style>
* {
margin: 0;
padding: 0;
}
#outer {
width: 520px;
height: 375px;
background-color: blue;
margin: 100px auto;
padding: 10px 0;
position: relative;
overflow: hidden;
}
img {
width: 500px;
height: auto;
}
#imgList {
list-style: none;
/* 开启绝对定位 */
position: absolute;
/* left: -520px; */
}
#imgList li {
float: left;
margin: 0 10px;
}
#navDiv {
position: absolute;
bottom: 14px;
}
#navDiv a {
float: left;
/* 设置浮动之后,行级元素会变成块级元素 */
width: 15px;
height: 15px;
border-radius: 50%;
margin: 0 5px;
background-color: red;
opacity: .5;
}
#navDiv a:hover {
background-color: black;
}
</style>
</head>
<body>
<div id="outer">
<ul id="imgList">
<li><img src="1.jpg" alt=""></li>
<li><img src="2.jpg" alt=""></li>
<li><img src="3.jpg" alt=""></li>
<li><img src="4.jpg" alt=""></li>
<li><img src="5.jpg" alt=""></li>
<li><img src="6.jpg" alt=""></li>
</ul>
<div id="navDiv">
<a href="#"></a>
<a href="#"></a>
<a href="#"></a>
<a href="#"></a>
<a href="#"></a>
</div>
</div>
<script src="/day7/move.js"></script>
<script>
//获取ul标签
var imgList = document.getElementById("imgList");
// 获取所有的img标签
var imgArr = document.getElementsByTagName("img");
// 设置ul的宽度
imgList.style.width = 520 * imgArr.length + "px";
//设置导航点居中显示
var navDiv = document.getElementById("navDiv");
//获取outer
var outer = document.getElementById("outer");
//设置动态居中
navDiv.style.left = (outer.offsetWidth - navDiv.offsetWidth) / 2 + "px";
//默认显示图片的索引
var index = 0;
//获取所有的a
var allA = document.getElementsByTagName("a");
allA[index].style.backgroundColor = 'black';
for (var i = 0; i < allA.length; i++) {
allA[i].num = i; //解决索引问题
allA[i].onclick = function() {
clearInterval(timer);
index = this.num;
// imgList.style.left = -520 * index + "px";
//使用move函数
move(imgList, "left", -520 * index, 20, function() {
autoChange();
});
setA();
}
}
//开启自动切换
autoChange();
//创建一个方法设置选中的a
function setA() {
for (var i = 0; i < allA.length; i++) {
if (index >= imgArr.length - 1) { //在最后一张时,直接跳转到第一张(最后一张和第一张一样)
index = 0;
imgList.style.left = 0 + "px";
}
allA[i].style.backgroundColor = ""; //内联样式优先级高,将内联样式设置为“”,则样式表里的样式和就会生效,hover就会起作用
}
allA[index].style.backgroundColor = "black";
}
var timer;
//设置一个自动切换函数
function autoChange() {
timer = setInterval(() => {
index++;
move(imgList, "left", -520 * index, 20, function() {
setA(); //变更图片的同时切换导航按钮
})
}, 3000);
}
</script>
</body>
</html>
虽然在代码注释中写了一些注意事项,但是感觉这些是一些小细节,重提一下
- 给轮播图的导航按钮绑定单击响应函数时,我自己想到解决索引问题的解决办法是利用立即执行函数,类似解决闭包产生的同类问题,但是后面就卡住了,因为后面自动切换那块还需要索引。后面看老师的解决方案,给每个元素a添加一个属性index,记录自己的索引,就解决了当前和之后自动切换的需要索引的问题
- 点击导航按钮时,切换颜色那块,因为我们改变的内联样式,内联样式的优先级较高,当我们点击时设置其内联样式为空(因为之前有设置它的第一个按钮的默认内联样式为红色),样式表的样式就会起作用,这样就可以在点击时,将其他导航点设置为红色,而被点击者为黑色
move()函数在下方,具体参数解释可以看注释
//封装样式改变函数
//move函数的参数
// 1.需要改变动画的对象,obj
// 2.需要执行变化的对象的属性是什么,attr
// 3.属性改变的目标值,target
// 4.属性改变的速度
// 5.回调函数
function move(obj, attr, target, speed, callback) {
//关闭上一个定时器,避免多次点击导致速度加快
clearInterval(obj.timer);
//获取运动时当前元素的位置
var current = parseInt(getStyle(obj, attr));
if (current > target) {
speed = -speed;//控制样式的改变方向
}
obj.timer = setInterval(() => {
//判断target是否大于
//获取obj原来的left值
var oldValue = parseInt(getStyle(obj, attr));
var newValue = oldValue + speed;
if ((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) {
newValue = target;
}
obj.style[attr] = newValue + "px";
if (newValue === target) {
clearInterval(obj.timer);
callback();
}
}, 30);
}
//封装获取元素当前样式的函数
function getStyle(obj, name) {
if (window.getComputedStyle) {
return getComputedStyle(obj, null)[name]; //IE9+
} else {
return obj.currentStyle[name];
}
}
有误之处,还望指出