一、思路
功能一:无缝轮播
1、设置轮播图自动移动-注意:设置轮播的时间一定要比运动函数里面的时间长
2、设置无缝轮播
2.1再首尾各增加一张轮播图--注意:记得要修改ul的宽度
2.2设置轮播图移动到首尾后,跳转到对应的轮播图上
功能二:设置左右点击按钮,使轮播图移动
3、设置左右点击按钮,使轮播图移动
3.1设置左右导航按钮
3.2设置点击按钮移动事件
3.3解决快速点击时出现的空白图片bug:一张图片移动完后才能进行点击,否则点击不生效,是使用未运动(false)或者运动中(true)状态来设置
功能三:指示器随轮播图移动而变换显示位置
4、设置指示器,轮播图移动,指示器随之变动
4.1添加指示器
4.2类似于选项卡功能:清除指示器所有颜色样式,用计数器进行点击计数,计数值当作索引号赋给指示器,对应的指示器显示红色
功能四:点击指示器,轮播图移动
5、设置点击指示器,轮播图随之移动
5.1设置指示器点击事件
5.2点击指示器,轮播图移动---注意:指示器的索引号要重新赋原来的值
功能五:鼠标点击移动,轮播图移动
6、移动轮播图--参考拖动效果
6.1设置鼠标按下事件
6.2找到当前鼠标按下去的位置---用于判断鼠标移动是向右还是左
6.3设置鼠标移动事件
6.4设置鼠标抬起,移动事件停止
//轮播图style样式
<style>
* {
padding: 0;
margin: 0;
}
.swiperBox {
width: 400px;
height: 200px;
margin-top: 100px;
margin-left: 500px;
position: relative;
}
.swiper {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
border: 3px solid red;
}
ul {
display: flex;
width: 2800px;
position: absolute;
left: -400px;
}
ul li {
width: 400px;
height: 200px;
text-align: center;
line-height: 200px;
list-style: none;
}
.swiper>div {
position: absolute;
width: 30px;
height: 30px;
border-radius: 50%;
background: rgba(134, 134, 135, 0.2);
font-size: 20px;
text-align: center;
line-height: 30px;
}
.swiper .navLeft {
left: 0px;
top: 50%;
transform: translateY(-50%);
}
.swiper .navRight {
right: 0px;
top: 50%;
transform: translateY(-50%);
}
.swiper>div:hover {
cursor: pointer;
}
.swiper ol {
width: 100px;
display: flex;
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
justify-content: space-around;
}
.swiper ol>li {
width: 10px;
height: 10px;
border-radius: 50%;
list-style: none;
background: rgba(108, 107, 107, 0.3);
}
.swiper ol .active {
background: red;
}
</style>
2、HTML内容
//html内容
<div class="swiperBox">
<div class="swiper">
<ul>
<!-- 2.1首部添加一个轮播图 -->
<li style="background-color:palegreen ;">元素五</li>
<li style="background-color:pink ;">元素一</li>
<li style="background-color:skyblue ;">元素二</li>
<li style="background-color:orange ;">元素三</li>
<li style="background-color:plum;">元素四</li>
<li style="background-color:palegreen ;">元素五</li>
<!-- 2.1尾部添加一个轮播图 -->
<li style="background-color:pink ;">元素一</li>
</ul>
<!-- 3.1设置左右导航按钮 -->
<div class="navLeft"><</div>
<div class="navRight">></div>
<!-- 4.1设置指示器 -->
<ol>
<li class="active"></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ol>
</div>
</div>
3、JS代码
<script>
const ulEle = document.querySelector('ul')
const swiperBoxELe = document.querySelector('.swiperBox')
let liEles = document.querySelectorAll('.swiper>ul>li')
let navCounts = liEles.length //轮播图个数
let navWidth = window.getComputedStyle(swiperBoxELe).width //轮播图的宽度,带有px
navWidth = parseInt(navWidth)
const navLeftEle = document.querySelector('.navLeft')
const navRightEle = document.querySelector('.navRight')
let ismove = false //未运动,true是运动中
let index = 0 //指示器索引号和计数器
let pointLi = document.querySelectorAll('ol>li')
//六、鼠标点击移动,轮播图移动
function mouseMove() {
//6.1设置鼠标按下事件
swiperBoxELe.addEventListener('mousedown', (e) => {
//6.2找到当前鼠标按下去的位置
e = e || window.e
let original = e.offsetX
//6.3设置鼠标移动事件
swiperBoxELe.onmousemove = function (e) {
e = e || window.e
//判断鼠标往哪边移动
let current = e.offsetX
if (current - original > 0) {
moveRight() //右移
}else{
moveLeft()
}
}
})
//6.4 设置鼠标抬起,移动事件停止
document.addEventListener('mouseup',()=>swiperBoxELe.onmousemove=null)
}
mouseMove()
//五、点击指示器,轮播图随之移动
//5.1设置指示器点击事件
function pointClick() {
for (let i = 0; i < pointLi.length; i++) {
pointLi[i].addEventListener('click', () => {
if (!ismove) {
//5.2点击指示器,轮播图移动
let index_d = i - index //当前点击的指示器索引号与前一个点击的指示器索引号差值
index = i //同步点击后的指示器索引号
move(ulEle, -navWidth * index_d)
clear()
pointActive(i)
}
})
}
}
pointClick()
//三、设置左右点击按钮,使轮播图移动
//3.2设置点击按钮移动事件
function navClick() {
//点击左边导航,轮播图向左移动
navLeftEle.addEventListener('click', () => {
moveLeft()
})
//点击右边导航,轮播图向右移动
navRightEle.addEventListener('click', () => {
moveRight()
})
}
navClick()
//轮播图右移,指示器随之变动
function moveRight() {
//3.3解决快速点击时出现的空白图片bug
if (!ismove) {
//4.2设置点击计数器,如果计数器为第一张轮播图,下次点击时则计数为最后一张轮播图
if (index == 0) {
index = navCounts - 3
} else {
index--
}
move(ulEle, navWidth)
clear()
pointActive(index)
}
}
//轮播图左移,指示器随之变动
function moveLeft() {
//3.3解决快速点击时出现的空白图片bug
if (!ismove) {
//4.2设置点击计数器,如果计数器为最后一张轮播图则计数清0
if (index == navCounts - 3) {
index = 0
} else {
index++
}
move(ulEle, -navWidth)
clear()
pointActive(index)
}
}
//清除指示器颜色样式
function clear() {
for (let i = 0; i < pointLi.length; i++) {
pointLi[i].className = ''
}
}
//轮播图移动,指示器随之变色
function pointActive(index) {
pointLi[index].className = 'active'
}
//一、轮播图自动移动
function autoplayMove() {
//设置定时器自动移动
setInterval(() => {
move(ulEle, -navWidth)
}, 2000)
}
// autoplayMove()
//运动函数
function move(ele, offset) {
//3.3运动中
ismove = true
//offset 偏移量-需要移动的总距离
let time = 1000 //移动花的总时间
let rate = 100 //速度-每次移动花的时间
let distance = (offset * rate) / time //每次移动的距离
ele.style.left = window.getComputedStyle(ele).left //设置初始位置的行内样式
let goal = parseInt(ele.style.left) + offset //移动后的位置
console.log(goal);
//设置移动的定时器
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) == -(navCounts - 1) * navWidth) { //轮播图向左移动的边界判定
ele.style.left = -navWidth + 'px'
} else if (parseInt(ele.style.left) == 0) {
ele.style.left = -((navCounts - 2) * navWidth) + 'px' //轮播图向右移动的边界判定
}
//3.3停止运动
ismove = false
} else {
ele.style.left = `${distance + parseInt(ele.style.left)}px`
}
}, rate)
}
</script>