html部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>轮播图</title>
<!-- 链接css -->
<link rel="stylesheet" href="./index.css">
<!-- 链接iconfont图标库 -->
<link rel="stylesheet" href="https://at.alicdn.com/t/font_2866970_cjlwyk672os.css">
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style: none;
}
</style>
</head>
<body>
<!-- 外部容器 -->
<div class="wrap">
<!-- 图片容器 -->
<ul class="slideshow">
<li><img src="../img/1.jpg" alt=""></li>
<li><img src="../img/2.jpg" alt=""></li>
<li><img src="../img/3.jpg" alt=""></li>
<li><img src="../img/4.jpg" alt=""></li>
<li><img src="../img/5.jpg" alt=""></li>
</ul>
<!-- 左箭头 -->
<i class="iconfont icon-youjiantou-cu"></i>
<!-- 右箭头 -->
<i class="iconfont icon-zuojiantou-cu"></i>
<!-- 轮播图导航 -->
<div class="slide-nav">
</div>
</div>
<script src="./index.js"></script>
<script>
/* 获取容器 */
var wrap = document.querySelector('.wrap');
/* 调用 */
new Swiper(wrap);
</script>
</body>
</html>
css部分
.wrap {
width: 800px;
height: 450px;
margin: 100px auto;
position: relative;
overflow: hidden;
cursor: pointer;
}
img {
/* 改变基线对齐方式 */
vertical-align: top;
}
.slideshow {
display: flex;
position: absolute;
left: 0;
top: 0;
}
.icon-youjiantou-cu,
.icon-zuojiantou-cu {
position: absolute;
top: 50%;
transform: translateY(-50%);
font-size: 48px;
color: #fff;
background-color: rgba(0, 0, 0, .4);
width: 55px;
height: 70px;
line-height: 70px;
text-align: center;
}
.icon-youjiantou-cu {
left: 0;
}
.icon-zuojiantou-cu {
right: 0;
padding-left: 5px;
box-sizing: border-box;
}
.slide-nav {
position: absolute;
left: 50%;
transform: translate(-50%);
bottom: 20px;
}
.slide-nav span {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
margin: 0px 5px;
background-color: rgba(255, 255, 255, .8);
}
.slide-nav span.active {
background-color: #00a1d6;
border: 2px solid #fff;
box-sizing: border-box;
transform: scale(1.3);
}
js部分
class Swiper {
constructor(el) {
// 轮播的容器
this.el = el;
// 左箭头
this.leftArrows = el.querySelector(".icon-youjiantou-cu");
//右箭头
this.rightArrows = el.querySelector(".icon-zuojiantou-cu");
//获取图片容器
this.ss = el.querySelector(".slideshow");
//获取图片的宽度
this.img_width = el.querySelector(".slideshow li").offsetWidth;
//获取图片的个数
this.len = el.querySelectorAll(".slideshow li").length;
//当前显示图片的索引。
this.index = 0;
//判断运动是否结束 true结束 false未结束
this.isRun = true;
this.init();
}
// 点击左箭头事件函数
leftClick() {
if (!this.isRun) {
return;
}
//判断是不是第一张
if (this.index == 0) {
//瞬间移动到最后一张 : left等于 li的个数-1 * li的宽度
this.ss.style.left = -this.len * this.img_width + "px";
//让索引来到最后一张
this.index = this.len;
}
this.index--;
activeDot(this.index);
this.isRun = false; //开始运动
move({
el: this.ss,
target: -this.index * this.img_width,
step: 20,
callback: this.callBack.bind(this)
})
}
// 右箭头事件函数
rightClick() {
if (!this.isRun) {
return;
}
//判断是不是最后一张
if (this.index == this.len) {
//瞬间移动到第一张
this.ss.style.left = "0px";
this.index = 0;
}
this.index++;
this.activeDot(this.index);
this.isRun = false; //开始运动
move({
el: this.ss,
target: -this.index * this.img_width,
step: 20,
callback: this.callBack.bind(this)
})
}
//激活小圆点导航
activeDot(num) {
//如果显示的是最后一张图片(复制的图片),第一个小圆点显示。
if (this.len == num) {
//让第一个小圆点激活。
num = 0;
}
//清除所有小圆点的active
for (var i = 0; i < this.dots.length; i++) {
this.dots[i].classList.remove("active");
}
//单独为激活的小圆点添加acative
this.dots[num].classList.add("active");
}
callBack() {
//运动结束
this.isRun = true;
}
//初始化中(不是属性也不是方法的写在这里)
init() {
//为左箭头绑定点击事件
this.leftArrows.onclick = this.leftClick.bind(this);
//为右箭头绑定点击事件
this.rightArrows.onclick = this.rightClick.bind(this);
//生成小圆点 有多少张图片就生成多少个小圆点
for (var i = 0; i < this.len; i++) {
var span = document.createElement("span");
this.el.querySelector(".slide-nav").appendChild(span);
}
//获取小圆点
this.dots = this.el.querySelectorAll(".slide-nav span");
//第一个添加默认的active类名
this.dots[0].classList.add("active")
//复制第一张图片插入到图片容器的末尾。
var firstImg = this.ss.firstElementChild.cloneNode(true);
this.ss.appendChild(firstImg);
//为小圆点添加点击事件
for (var i = 0; i < this.dots.length; i++) {
this.dots[i].index = i;
var that = this;
this.dots[i].onclick = function() {
//更新index的值
that.index = this.index;
//激活图片对应的小圆点导航。
that.activeDot(that.index);
//运动
move({
el: that.ss,
target: -that.index * that.img_width,
step: 20,
callback: function() {
//运动结束
that.isRun = true;
}
})
}
}
}
}
/**
* 让元素移动
* @param {*} obj 参数对象
*/
function move(obj) {
// 如果已经存在定时器,就不再开启了
var el = obj.el;
var target = obj.target;
var callback = obj.callback;
var step = obj.step;
var attr = obj.attr;
clearInterval(el.timer)
if (!attr) { //如果attr的默认值为undefined。
attr = "left";
}
if (!step) { //如果attr的默认值为undefined。
step = 7;
}
//获取元素的样式
var res = getComputedStyle(el)[attr];
//字符串转数字
res = parseInt(res);
//判断移动的方向: 盒子的偏移量-终点 如果大于0 说明盒子在右,速度为负数, 如果小于0 说明盒子在左,速度为正
if (res - target > 0) {
//求绝对值取反。
step = -Math.abs(step);
}
//让el对象上添加了一个属性 timer 值为定时器的ID。
el.timer = setInterval(function() {
//获取最新的res的值
var res = getComputedStyle(el)[attr];
//字符串转数字
res = parseInt(res);
// 计算这次运动后的位置。 此时还没有真正的运动、
var arrived = res + step;
// 判断运动是否结束
if ((step > 0 && arrived >= target) || (step < 0 && arrived <= target)) {
//结束运动 : 清除定时器,
clearInterval(el.timer)
// 将物体直接运动到终点
el.style[attr] = target + "px";
//清除el元素上的定时器属性,以便下一次运动开始。
el.timer = null;
//运动结束后,调用回调函数、
if (callback) { //判断callback是否存在,存在才会执行该函数。
callback();
}
} else {
//运动没有结束,修改left的值让它继续运动。
el.style[attr] = arrived + "px";
}
}, 16);
}