- 可控制是否自动轮播
- 左右箭头切换上一张,下一张,节流处理
- 鼠标放到箭头上,图片停止自动轮播,鼠标移开接着继续播放
- 点击小圆点可跳转到对应顺序的图片
- 移动端可左滑、右滑切换
实现思路:
html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>轮播图</title>
<link rel="stylesheet" href="css/轮播图.css">
<script src="js/轮播图.js"></script>
</head>
<body>
<div class="wrapper">
<a href="javascipt:;" class="prev"></a> //href=''可实现不跳转的功能
<ul class="img_wrapper">
<li><img src="img/img1.jpg"></img></li>
<li><img src="img/img2.jpg"></img></li>
<li><img src="img/img3.jpg"></img></li>
<li><img src="img/img4.jpg"></img></li>
<li><img src="img/img5.jpg"></img></li>
<li><img src="img/img6.jpg"></img></li>
</ul>
<a href="javascipt:;" class="next"></a>
<ul class="circle"> //这里是存放小圆圈,在js会根据图片的数量来添加
</ul>
</div>
</body>
</html>
复制代码
css代码:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul {
list-style: none;
}
.wrapper {
position: relative;
width: 500px;
height: 350px;
background-color: pink;
margin: 100px auto;
overflow: hidden; //只显示一张图片,其余图片隐藏
}
.img_wrapper {
position: absolute; //使用绝对定位要记住“子绝父相”(子元素使用绝对定位,父元素则使用相对定位)
top: 0;
width: 0;
width: 700%; //这里注意不是一张图片的宽度,而是全部图片的宽度,使这个图片的盒子能刚好装下所有图片
height: 350px;
}
.img_wrapper > li {
float: left; //向左浮动使图片盒子li一行排列并且没有空隙
width: 500px;
height: 350px;
}
.img_wrapper > li > img {
width: 500px; //让图片的宽高等于父盒子的父盒子的宽高
height: 350px;
}
.wrapper > a { //这是上一张图片和下一张图片按钮的共同属性
position: absolute;
top: 50%;
width: 35px;
height: 35px;
margin-top: -17.5px;
background-color: rgba(0, 0, 0, 0.3);
z-index: 3;
display: none;
}
.prev {
left: 0;
background: url("../img/prev.png") no-repeat center;
}
.next {
right: 0;
background: url("../img/next.png") no-repeat center;
}
.circle {
position: absolute;
display: flex;
justify-content: space-between;
align-items: center;
bottom: 10px;
left: 50%;
background-color: rgba(245, 245, 245, 0.4);
padding: 2px 5px;
border-radius: 5px;
}
.circle > li {
width: 9px;
height: 9px;
border-radius: 50%;
border: 1px solid white;
margin: 0 3px;
cursor: pointer;
}
.current { //这个属性是给小圆圈添加的,当前图片对应的小圆圈背景变为白色
background-color: white;
}
复制代码
js代码:
window.addEventListener("DOMContentLoaded", function () {
var wrapper = document.querySelector(".wrapper");
var prev = document.querySelector(".prev");
var next = document.querySelector(".next");
var img_wrapper = document.querySelector(".img_wrapper");
var circle = document.querySelector(".circle");
//flag是用来判断上一个动画是否已经完成,完成才能进行下一个动画(这里的动画指图片左右滑动的动画)
var flag = true;
var num = 0; //num用于判断是第几张图片
var timerA = setInterval(() => { //这个定时器实现自动播放下一张图片的效果
next.click(); //自动播放下一张不是直接改变这个盒子的位移,而是通过点击next按钮
}, 1500);
//利用for循环生成circle
for (var i = 0; i < img_wrapper.children.length; i++) {
var li = document.createElement("li");
circle.appendChild(li);
//使用setAttribute给小圆圈添加index这个自定义属性,并且赋值,以便后续通过index获取当前是第几张图片
li.setAttribute("index", i);
li.addEventListener("click", function () {
for (var j = 0; j < circle.children.length; j++) {
circle.children[j].className = "";
}
this.className = "current"; //每次点击小圆圈则该小圆圈变成白色,其余颜色变为透明(排他思想)
num = this.getAttribute("index");
animate( //实现点击小圆圈也可以切换图片
img_wrapper,
-img_wrapper.parentElement.offsetWidth * this.getAttribute("index")
);
});
}
//由于播放到最后一张图片后再点击下一张图片动画会返回第一张,并且画面非常不好看,要实现无缝切换图片即需将第一张图片复制放到最后面。由于添加小圆圈的代码是在复制第一张图片之前执行的,因此小圆圈的数量不会受影响。
var firstImg = img_wrapper.children[0].cloneNode(true);//创建节点
img_wrapper.appendChild(firstImg);//添加节点
var circleLis = circle.querySelectorAll("li");//将所有小圆圈添加到数组里
circleLis[0].className = "current";//默认第一个小圆圈为当前状态
//由于在css中left是50%,因此不是居中的状态,当我们把圆圈添加后获取整个盒子的长度,使marginLeft等于负的盒子的一半即可实现居中效果
circle.style.marginLeft = -(circle.offsetWidth / 2) + "px";
//当我们鼠标不在图片的盒子中时,不显示切换图片的两个按钮,这里实现鼠标在盒子上方时按钮显示,并且暂停自动播放图片的功能
wrapper.addEventListener("mouseenter", function () {
prev.style.display = "block";
next.style.display = "block";
clearInterval(timerA); //清除定时器,暂停自动播放的功能
timerA = null;
});
//鼠标离开盒子上方,按钮隐藏,开始自动播放的功能
wrapper.addEventListener("mouseleave", function () {
prev.style.display = "none";
next.style.display = "none";
timerA = setInterval(() => { //添加定时器,开始自动播放的功能
next.click();
}, 1500);
});
next.addEventListener("click", function () {
if (flag) { //flag判断是否上一个动画已完成
flag = false;//当开始这一次的动画(切换图片)时,使flag为false,这样再点击按钮就不会开始下一个动画
//判断是否是最后一张图片,最后一张图片与第一张图片一样,如果已经是最后一张图片了,使图片盒子的left值立即回到0,即初始位置,这样在切换下一张图片时就会切换到第二张图片
if (num == img_wrapper.children.length - 1) {
img_wrapper.style.left = 0 + "px";
num = 0;
}
num++;
animate(
img_wrapper,
-num * img_wrapper.parentElement.offsetWidth,
function () {
flag = true;
}
//动画结束,使flag=true
);
//这里改变小圆圈的背景颜色,使小圆圈的背景颜色随着图片的切换而改变
for (var i = 0; i < circleLis.length; i++) {
circleLis[i].className = "";
if (num == img_wrapper.children.length - 1) {
//当图片是最后一张时,第一个小圆圈改变背景颜色
circleLis[0].className = "current";
} else {
circleLis[num].className = "current";
}
}
}
});
//上一张图片的按钮代码与下一张的相似
prev.addEventListener("click", function () {
if (flag) {
if (num == 0) {
num = img_wrapper.children.length - 1;
img_wrapper.style.left =
-num * img_wrapper.parentElement.offsetWidth + "px";
}
num--;
animate(
img_wrapper,
-num * img_wrapper.parentElement.offsetWidth,
function () {
flag = true;
}
);
for (var i = 0; i < circleLis.length; i++) {
circleLis[i].className = "";
circleLis[num].className = "current";
}
}
});
//切换图片的动画
//obj:目标盒子,target:需要移动的距离
function animate(obj, target, callback) {
clearInterval(obj.timer);//首先先清除定时器,防止过多定时器的叠加
obj.timer = setInterval(() => {
if (obj.offsetLeft == target) {//当目标盒子的left值等于目标距离时清除定时器
clearInterval(obj.timer);
// if (callback) {
// callback();
// }相当于:
callback && callback();
} else {
obj.step = (target - obj.offsetLeft) / 10; //这行代码可以实现变速的移动,不懂的自己代入数值计算
if (obj.step >= 0) {
obj.step = Math.ceil(obj.step);
} else {
obj.step = Math.floor(obj.step);
}
obj.style.left = obj.offsetLeft + obj.step + "px";
}
}, 15);
}
});
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END