Appearance
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>Document</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
overflow: hidden;
}
.container {
width: 1226px;
height: 460px;
margin: 0 auto;
position: relative;
box-sizing: border-box;
overflow: hidden;
}
.container .wrapper {
position: absolute;
top: 0;
left: 0;
width: 6130px; /* calc(1226px * 5); */
height: 100%;
transition: left linear;
}
.container .wrapper .slide {
float: left;
width: 1226px;
height: 100%;
background: #eee;
}
.container .wrapper .slide .banner-img {
width: 100%;
height: 100%;
display: block;
cursor: pointer;
}
.container .pagination {
width: 400px;
height: 21px;
position: absolute;
right: 38px;
bottom: 20px;
text-align: right;
user-select: none;
}
.container .pagination .btn {
width: 8px;
height: 8px;
display: inline-block;
border: 2px solid #fff;
border-color: hsla(0, 0%, 100%, .3);
border-radius: 10px;
background: rgba(0, 0, 0, .4);
opacity: .8;
transition: all .2s;
cursor: pointer;
}
.container .pagination .btn.active {
background: rgba(255, 255, 255, .4);
border-color: rgba(0, 0, 0, .4);
transform: scale(1.2);
}
.container .navigation .navigation-btn {
width: 41px;
height: 69px;
display: block;
position: absolute;
top: 196px; /* calc(460px / 2 - 69px / 2) */
background: url('./pagination.png') no-repeat;
}
.container .navigation .prev {
background-position-x: -83px;
}
.container .navigation .prev:hover {
background-position-x: 0px;
}
.container .navigation .next {
right: 0;
background-position-x: -124px;
}
.container .navigation .next:hover {
background-position-x: -41px;
}
</style>
</head>
<body>
<section class="container">
<!-- 轮播图 -->
<div class="wrapper">
<div class="slide">
<img class="banner-img" src="./1.jpg" alt="">
</div>
<div class="slide">
<img class="banner-img" src="./2.webp" alt="">
</div>
<div class="slide">
<img class="banner-img" src="./3.webp" alt="">
</div>
<div class="slide">
<img class="banner-img" src="./4.webp" alt="">
</div>
<div class="slide">
<img class="banner-img" src="./1.jpg" alt="">
</div>
</div>
<!-- 分页器 -->
<div class="pagination">
<span class="btn active"></span>
<span class="btn"></span>
<span class="btn"></span>
<span class="btn"></span>
</div>
<!-- 导航按钮 -->
<div class="navigation">
<a href="javascript:;" class="navigation-btn prev"></a>
<a href="javascript:;" class="navigation-btn next"></a>
</div>
</section>
<script>
function debounce (func, wait = 300, immediate = false) {
let timer = null
return function anonymouse (...args) {
let now = immediate && !timer
// 每次点击都把之前定时器清楚
clearTimeout(timer)
// 设置一个新的定时器来监听wait时间内是否有触发第二次
timer = setTimeout(() => {
// 手动让其回归到初始状态
timer = null
// wait这么久的等待中.没有出发第二次
!immediate ? func.call(this, ...args) : null
}, wait)
// 如果立即执行
now ? func.call(this, ...args) : null
}
}
const bannerModule = (function () {
let $container = $('.container'),
$wrapper = $container.find('.wrapper'),
$pagination = $container.find('.pagination'),
$paginationList = $pagination.find('.btn'),
$navigation = $container.find('.navigation'),
$prev = $navigation.find('.prev'),
$next = $navigation.find('.next')
let index = 0, // slide索引
interval = 1000, // 轮播时间
timer = null // 定时器返回值 定时器有返回值,是一个数字,代表当前是第几个定时器,清除的时候根据这个号码清除
// 自动轮播
const autoMove = function autoMove () {
if (index >= 4) {
// 当前显示的是克隆的那一张图片,需要立即运动到真实的第一张
index = 0
$wrapper.css('left', 0)
}
index++
$wrapper.stop().animate({
left: index * -1226
}, 300)
// 每次切换都要控制分页器对齐
paginationFocus()
}
// 分页器对齐
const paginationFocus = function paginationFocus () {
let temp = index
temp === 4 ? temp = 0 : null
$paginationList.each((idx, item) => {
let $item = $(item)
if (temp === idx) {
$item.addClass('active')
return
}
$item.removeClass('active')
})
}
// 点击分页器切换图片
$paginationList.click(debounce(function () {
let clickIndex = $(this).index()
console.log(index)
if (index === clickIndex || (index === 4 && clickIndex === 0)) return
index = clickIndex
$wrapper.stop().animate({
left: index * -1226
}, 300)
paginationFocus()
}, 300, true))
// 导航按钮
const handleNavgation = function handleNavgation () {
// 点击右导航按钮功能和自动轮播的功能一样,都是切换到下一张
$next.click(debounce(autoMove, 300, true))
// 点击左导航按钮切换
$prev.click(debounce(function () {
if (index <= 0) {
index = 4
$wrapper.css('left', index * -1226)
}
index--
$wrapper.stop().animate({
left: index * -1226
}, 300)
paginationFocus()
}, 300, true))
}
return {
init () {
timer = setInterval(autoMove, interval)
$container.on('mouseenter', function () {
// 鼠标进入容器,停止轮播
clearInterval(timer)
}).on('mouseleave', function () {
// 鼠标离开容器,开始轮播
timer = setInterval(autoMove, interval)
})
handleNavgation()
}
}
})()
bannerModule.init()
</script>
</body>
</html>