主要实现自动轮播功能、定位功能、上一页下一页功能。
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>
<link rel="stylesheet" href="./css/swiper.css">
</head>
<body>
<div class="swiper-wraper" id="swiperroot">
<div class="swiper">
<ul>
<li><img src="./image/img01.jpg" alt="img01"></li>
<li><img src="./image/img02.jpg" alt="img02"></li>
<li><img src="./image/img03.jpg" alt="img03"></li>
<li><img src="./image/img05.jpg" alt="img05"></li>
</ul>
<a class="prev" href="javascript:void(0)"><</a>
<a class="next" href="javascript:void(0)">></a>
<!-- 指示器 -->
<ul class="pointer-wraper"></ul>
</div>
</div>
<script src="./js/swiper.js"></script>
<script>
let swiper = new Swiper('#swiperroot')
swiper.init()
swiper.autoPlay()
</script>
</body>
</html>
CSS代码
* {
padding: 0;
margin: 0;
}
ul,
li {
list-style: none;
}
a{
text-decoration: none;
}
.swiper-wraper {
position: relative;
width: 800px;
height: 400px;
margin: 100px auto;
}
.swiper-wraper .swiper {
position: absolute;
width: 100%;
height: 100%;
/* border: 10px solid rgb(15, 15, 15); */
overflow: hidden;
}
.swiper-wraper .swiper ul {
position: absolute;
left: -800px;
display: flex;
}
.swiper-wraper .swiper ul li {
width: 100%;
height: 100%;
text-align: center;
line-height: 200px;
font-size: 28px;
}
.swiper-wraper .swiper ul li img{
width: 800px;
height: 400px;
}
/* 导航 */
.swiper-wraper .swiper .prev{
display: inline-block;
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 30px;
height: 80px;
line-height: 80px;
background-color: rgba(0, 0, 0,.6);
text-align: center;
color: white;
font-size: 28px;
}
.swiper-wraper .swiper .next{
display: inline-block;
position: absolute;
top: 50%;
right: 0;
transform: translateY(-50%);
width: 30px;
height: 80px;
line-height: 80px;
background-color: rgba(0, 0, 0,.6);
text-align: center;
color: white;
font-size: 28px;
}
.swiper-wraper .swiper .pointer-wraper{
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
width: 100px;
display: flex;
justify-content: space-between;
}
.swiper-wraper .swiper .pointer-wraper li{
width: 10px;
height: 10px;
border-radius: 50%;
background-color: white;
}
.swiper-wraper .swiper .pointer-wraper .active{
background-color: red;
}
JS代码(采用类对象)
class Swiper {
constructor(id) {
this.rootEle = document.querySelector(id)
this.ulEle = this.rootEle.querySelector('ul') //轮播ul
this.swiper = this.rootEle.querySelector('.swiper') //相框
this.offset = parseInt(window.getComputedStyle(this.swiper).width) //相框宽及偏移量
this.count = this.ulEle.children.length //轮播元素个数, 5
this.nextEle = this.rootEle.querySelector('.next') // 下一张
this.prevEle = this.rootEle.querySelector('.prev') //上一张
this.isMove = false //轮播图是否在运动
this.index = 0 //指示器索号
this.num = this.ulEle.children.length
}
/**
* 初始化动态生成节点
*/
init() {
//1. 克隆第一张轮播图片放到最后面
let firstEle = this.ulEle.firstElementChild.cloneNode(true)
//2. 克隆最后一张轮播图放到最前面
let lastEle = this.ulEle.lastElementChild.cloneNode(true)
//3. 父元素.appendChild(子元素)
this.ulEle.appendChild(firstEle)
//4. 父元素.insertBefore(子元素,新元素)
this.ulEle.insertBefore(lastEle, this.ulEle.firstElementChild)
//5. 创建指示器
let pointerEle = this.rootEle.querySelector('.pointer-wraper')
for (let i = 0; i < this.count; i++) {
let liEle = document.createElement('li') //<li class="active"></li>
if (i == 0) {
liEle.className = 'active'
}
pointerEle.appendChild(liEle)
}
this.count = this.ulEle.children.length //轮播元素个数
this.pointerEles = this.rootEle.querySelectorAll('.pointer-wraper>li')
this.onNextPrev()
this.onPointer()
}
/**
* 自动轮播
*/
autoPlay() {
setInterval(() => {
//调用运动函数move
this.onNext()
}, 2000)
}
/**
* 上一张和下一张事件绑定
*/
onNextPrev() {
this.nextEle.onclick = () => this.onNext()
this.prevEle.onclick = () => this.onPrev()
}
/**
* 下一张
*/
onNext() {
//判断轮播是否在运动,没有运动时执行里面代码
if (this.isMove == false) {
//轮播图运行
this.move(this.ulEle, -this.offset)
//改变指示器序号
if (++this.index > this.num - 1) {
this.index = 0
}
this.setAtive(this.index) //设置指示器效果
}
}
/**
* 上一张
*/
onPrev() {
if (this.isMove == false) {
this.move(this.ulEle, this.offset)
if (--this.index < 0) {
this.index = this.num - 1
}
this.setAtive(this.index)
}
}
/**
* 清除所有指示器效果
*/
setAtive(index) {
//清除所有指示器效果
for (let i = 0; i < this.pointerEles.length; i++) {
this.pointerEles[i].classList.remove('active')
}
//设置当前指示器效果
this.pointerEles[index].classList.add('active')
}
/**
* 指示器选中效果
*/
onPointer() {
//绑定指示器点击事件
for (let i = 0; i < this.pointerEles.length; i++) {
this.pointerEles[i].onclick = () => {
if (this.isMove == false) {
// i表示:当前点击的指示器序号
// _this.index表示:原来指示器序号,如果开启自动轮播,会动态变化
let mIndex = i - this.index //计算差值,
this.index = i //同步当前点击的指示器序号给外面的index
this.setAtive(i) //设置指示器效果
//轮播图同步运动
this.move(this.ulEle, -this.offset * mIndex)
}
}
}
}
move(ele, _offset) {
this.isMove = true //开始运动
//设置元素初始位置
ele.style.left = window.getComputedStyle(ele).left
let width = Math.abs(_offset)
let count = this.count
let offset = _offset //移动的距离
let goal = parseInt(ele.style.left) + offset //目标位置
let rate = 20 //移动速度
let time = 1000 //移动总时间
let distance = rate * offset / time
let timer = setInterval(() => {
if (parseInt(ele.style.left) == goal ||
Math.abs((Math.abs(goal) - Math.abs(parseInt(ele.style.left)))) < Math.abs(distance)) {
ele.style.left = goal + 'px'
clearInterval(timer)
//每次轮播结束时判断
//向左运行
if (parseInt(ele.style.left) == -(count - 1) * width) {
ele.style.left = -width + 'px'
}
if (parseInt(ele.style.left) == 0) {
ele.style.left = -(count - 2) * width + 'px'
}
this.isMove = false
} else {
ele.style.left = parseInt(ele.style.left) + distance + 'px'
}
}, rate)
}
}