轮播效果的实现
<!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>轮播效果1</title>
<style>
* {
padding: 0;
margin: 0;
}
ul,
li {
list-style: none;
}
a {
text-decoration: none;
color: black;
}
.swiper-wraper {
position: relative;
width: 400px;
height: 200px;
margin-top: 100px;
margin-left: 500px;
}
.swiper-wraper .swiper {
position: relative;
width: 100%;
height: 100%;
/* border: 4px solid gray; */
overflow: hidden;
}
.swiper-wraper .swiper ul {
position: absolute;
top: 0;
left: -400px;
display: flex;
width: 2800px;
}
.swiper-wraper .swiper ul li {
width: 400px;
height: 200px;
text-align: center;
line-height: 200px;
user-select: none;
}
/* 导航 */
.swiper-wraper .swiper .prev {
width: 30px;
height: 60px;
line-height: 60px;
background-color: rgba(34, 33, 33, 0.6);
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
font-size: 18px;
text-align: center;
}
.swiper-wraper .swiper .next {
width: 30px;
height: 60px;
line-height: 60px;
background-color: rgba(34, 33, 33, 0.6);
position: absolute;
top: 50%;
right: 0;
transform: translateY(-50%);
font-size: 18px;
text-align: center;
}
/* 指示器 */
.swiper-wraper .swiper ol {
position: absolute;
left: 50%;
bottom: 20px;
transform: translateX(-50%);
width: 100px;
display: flex;
justify-content: space-between;
}
.swiper-wraper .swiper ol li {
width: 10px;
height: 10px;
border-radius: 50%;
background-color: rgb(108, 107, 109);
}
.swiper-wraper .swiper ol li:hover {
cursor: pointer;
}
.swiper-wraper .swiper ol .active {
background-color: red;
}
</style>
</head>
<body>
<!-- 轮播容器 -->
<div class="swiper-wraper">
<!-- 相框 -->
<div class="swiper">
<ul>
<li style="background-color: cadetblue">元素五</li>
<li style="background-color: skyblue">元素一</li>
<li style="background-color: blueviolet">元素二</li>
<li style="background-color: pink">元素三</li>
<li style="background-color: burlywood">元素四</li>
<li style="background-color: cadetblue">元素五</li>
<li style="background-color: skyblue">元素一</li>
</ul>
<!-- 导航 -->
<!-- 下一页 -->
<a href="javascript:void(0)" class="next">></a>
<!-- 上一页 -->
<a href="javascript:void(0)" class="prev"><</a>
<!-- 指示器 -->
<ol>
<li class="active"></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ol>
</div>
</div>
<script>
const swiperWraper = document.querySelector('.swiper-wraper')
const ulEle = document.querySelector('ul')
const nextEle = document.querySelector('.next')
const prevEle = document.querySelector('.prev')
const olLis = document.querySelectorAll('ol>li')
let swiperWidth = window.getComputedStyle(swiperWraper).width // 轮播元素宽
swiperWidth = parseInt(swiperWidth)
let count = ulEle.children.length // 元素个数
let isMove = false // 默认未运动, true运动中
let index = 0 // 指示器索引号,决定当前元素
/*
滑动效果
联想: 拖拽效果
*/
function setSwiperTouch() {
swiperWraper.onmousedown = function (e) {
e = e || window.event
let initX = e.offsetX
swiperWraper.onmousemove = function (e) {
e = e || window.event
let x = e.offsetX
// 向右
if (x - initX > 0) {
setPrev()
} else {
setNext()
}
}
document.onmouseup = () => (swiperWraper.onmousemove = null) // 注销移动事件
}
}
setSwiperTouch()
/*
指示器
联想: 选项卡
思路: 循环给每个选项绑定事件
清除所有选项卡选中效果
给当前元素设置选中效果
*/
function setPointer() {
// 给所有指示器绑定点击事件
for (let i = 0; i < olLis.length; i++) {
olLis[i].addEventListener('click', function () {
if (isMove == false) {
let index_d = i - index // 索引号差值
index = i // 同步指示器
move(ulEle, -swiperWidth * index_d)
setCurrentActive(i)
}
})
}
}
setPointer()
/*
清除所有指示器选中效果
*/
function clear() {
for (let i = 0; i < olLis.length; i++) {
olLis[i].classList.remove('active')
}
}
/*
设置当前指示器效果
*/
function setCurrentActive(_index) {
clear()
olLis[_index].classList.add('active')
}
/**
* 绑定导航事件
*/
function bindNavigator() {
nextEle.addEventListener('click', () => setNext())
prevEle.addEventListener('click', () => setPrev)
}
/*
下一页
*/
function setNext() {
if (isMove == false) {
if (++index == count - 2) {
index = 0
}
setCurrentActive(index)
move(ulEle, -swiperWidth)
}
}
/*
上一页
*/
function setPrev() {
if (!isMove) {
if (--index < 0) {
index = count - 3
}
setCurrentActive(index)
move(ulEle, swiperWidth)
}
}
bindNavigator()
/**
* 自动轮播
*/
function autoPlay() {
setInterval(function () {
move(ulEle, -swiperWidth)
}, 2000)
}
// autoPlay()
/*
运动函数
ele 运动元素
offset 是运动总距离,偏移量 正向右,负向左
*/
function move(ele, offset) {
isMove = true // 开始运动
let _width = Math.abs(offset) //运动宽度
let time = 1000 // 总时间
let rate = 30 // 速度
let distance = (offset * rate) / time // 每次移动距离
//初始化当前位置
ele.style.left = window.getComputedStyle(ele).left
let init = parseInt(ele.style.left)
// 计算目标位置
let goal = init + offset
const timer = setInterval(function () {
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'
} else if (parseInt(ele.style.left) == 0) {
// 向左边界判断
ele.style.left = -(count - 2) * _width + 'px'
}
isMove = false // 停止运动
} else {
ele.style.left = parseInt(ele.style.left) + distance + 'px'
}
}, rate)
}
</script>
</body>
</html>
可以用swiper组件可实现更多功能的,详情可去官网