需求文档
轮播图(焦点图)需求
- 做一个轮播图功能,能够循环自动轮播,当播到最后一张图片时,再播就要播第一张图片
- 鼠标放到轮播图窗口上,要停止自动轮播,并且左右两个小箭头要出来。点击两个小箭头可以手动切换,点击左侧的小箭头,切换上一张,点击右侧的小箭头,切换至下一张;当鼠标画出时,轮播图还要恢复自动轮播
- 轮播的时候下面的小点要跟着动,上面显示的第几张图片,下面第几个小点要选中
- 点击的这些小点,上面的图片也会跟着切换到对应的图片
轮播图的原理(左右轮播)
- 在外层有一个 container 的盒子,宽高只能显示一张图片,并且设置 overflow:hidden;// 溢出隐藏
在 container 下面有一个叫做 wrapper 的盒子,wrapper 相对于 container 绝对定位,wrapper 里有很多图片,这些图片尺寸都是相同的,并且在一行排列
- 所谓轮播:container 默认展示第一张图片(索引为0的),wrapper 的 left 值为0。当第一次轮播后,container 展示图片为第二张图片(索引为1的图片),此时 wrapper 的 left 值是负的一张图片的宽度,第二次轮播后 container 展示的第三张图片(索引为2的图片),此时 wrapper 的 left 的值是多少:负的2张图片的宽度。。。。依次类推,wrapper 的 left 的值和 container 正在展示的图片索引的关系是:wrapper 的 left 值 = -1 索引 图片宽
- 实现轮播:我们设置一个变量 step,默认值0,表示 container 正在展示的图片索引。 向后轮播一次,给stepIndex++,然后把 wrapper 的 left 设置成:-1 stepIndex 图片宽
轮播图的无缝轮播原理: 向 wrapper 的末尾多拼接一个第一张图片,当轮播的时候,轮播到最后一张图片时,最后这张图片和第一张图片长得一模一样,此时我们把 wrapper 的 left 的值设置成0,left 为0时,container 展示的还是第一张图片,因为设为0的这个操作特别快,给人的感觉就是无缝轮播的;
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>轮播图左右运动版</title>
<!-- IMPORT CSS -->
<link rel="stylesheet" href="css/reset.min.css">
<style>
.container {
position: relative;
box-sizing: border-box;
margin: 0 auto;
width: 1200px;
height: 240px;
overflow: hidden;
}
.container .wrapper {
position: absolute;
top: 0;
left: 0;
box-sizing: border-box;
width: 6000px;
height: 100%;
display: flex;
}
.container .wrapper .slider {
box-sizing: border-box;
width: 1200px;
height: 100%;
}
.container .wrapper .slider img {
width: 100%;
height: 100%;
}
/* 分页器 */
.pagenition {
position: absolute;
z-index: 999;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
padding: 5px 10px;
background: rgba(255, 255, 255, .3);
font-size: 0;
border-radius: 26px;
}
.pagenition li {
display: inline-block;
margin: 0 10px;
width: 16px;
height: 16px;
border-radius: 50%;
background: lightblue;
cursor: pointer;
}
.pagenition li.active {
background: lightcoral;
}
/* 左右按钮 */
.arrow {
display: none;
position: absolute;
z-index: 999;
top: 50%;
margin-top: -22.5px;
width: 30px;
height: 45px;
background: url(images/pre.png) no-repeat 0 0;
}
.arrow.changeLeft {
left: 0;
}
.arrow.changeRight {
right: 0;
background-position: -50px 0;
}
.container:hover .arrow {
display: block;
}
</style>
</head>
<body>
<!-- 轮播图容器 -->
<div class="container">
<!-- WRAPPER存放所有的图 -->
<div class="wrapper">
<!-- SLIDER每一个轮播图 -->
<div class="slider">
<img src="images/banner01.png" alt="">
</div>
<div class="slider">
<img src="images/banner02.png" alt="">
</div>
<div class="slider">
<img src="images/banner03.jpg" alt="">
</div>
<div class="slider">
<img src="images/banner04.png" alt="">
</div>
<!-- 克隆的那份(无缝衔接) -->
<div class="slider">
<img src="images/banner01.png" alt="">
</div>
</div>
<!-- PAGENATION分页器 -->
<ul class="pagenition">
<li class="active"></li>
<li></li>
<li></li>
<li></li>
</ul>
<!-- 左右按钮 -->
<a href="javascript:;" class="arrow changeLeft"></a>
<a href="javascript:;" class="arrow changeRight"></a>
</div>
<!-- IMPORT JS -->
<script src="js/jquery.min.js"></script>
<script src="js/banner.js"></script>
</body>
</html>
js
// 防抖
function debounce(func, wait, immediate) {
let timer = null,
result = null;
return function anonymous(...args) {
let context = this,
now = immediate && !timer;
clearTimeout(timer);
timer = setTimeout(() => {
timer = null;
!immediate ? result = func.call(context, ...args) : null;
}, wait);
now ? result = func.call(context, ...args) : null;
return result;
}
}
let bannerModule = (function () {
let $container = $('.container'),
$wrapper = $container.find('.wrapper'),
$changeLeft = $container.find('.changeLeft'),
$changeRight = $container.find('.changeRight'),
$pagenition = $container.find('.pagenition'),
$pagenitionList = $pagenition.find('li');
let step = 0,
autoTimer = null,
interval = 1000;
// 自动轮播
function autoMove() {
step++;
if (step >= 5) {
$wrapper.css('left', 0);
step = 1;
}
$wrapper.stop().animate({
left: -step * 1200
}, 300);
// 自动焦点对齐
autoFocus();
}
// 自动对焦
function autoFocus() {
let temp = step;
temp === 4 ? temp = 0 : null;
$pagenitionList.each((index, item) => {
let $item = $(item);
if (index === temp) {
$item.addClass('active');
return;
}
$item.removeClass('active');
});
}
// 点击焦点切换到指定的位置
function handlePagenition() {
$pagenitionList.click(debounce(function () {
let index = $(this).index();
step = index;
$wrapper.stop().animate({
left: -step * 1200
}, 300);
autoFocus();
}, 300, true));
}
// 点击按钮处理
function handleArrow() {
// 右按钮处理(和自动一样)
$changeRight.click(debounce(autoMove, 300, true));
// 左按钮处理
$changeLeft.click(debounce(function () {
step--;
if (step < 0) {
$wrapper.css('left', -4 * 1200);
step = 3;
}
$wrapper.stop().animate({
left: -step * 1200
}, 300);
autoFocus();
}, 300, true));
}
return {
init() {
autoTimer = setInterval(autoMove, interval);
// 控制自动轮播的暂停和开始
$container.on('mouseenter', () => clearInterval(autoTimer))
.on('mouseleave', () => autoTimer = setInterval(autoMove, interval));
// 焦点点击
handlePagenition();
// 按钮点击
handleArrow();
}
}
})();
bannerModule.init();