DOM 4步
1.查找触发事件的元素
2.绑定事件处理函数
3.查找要修改的元素
4.修改元素
结构
div#banner-container(主框)
ul#banner-wrapper>li>a>img(图片内容)
banner-btn-left,banner-btn-right
ul#banner-contorl>li(圆点) :active(选中状态)
注意:
轮播图移动的是ul而不是li
- 鼠标移入移出挂到主框上
步骤
1.定义函数用于切换索引显示效果(且完善切换效果)
2.定义函数执行左右按钮切换功能(调用1)
3.定时器定时调用切换图片(调用1)
4.圆点点击切换功能(调用1)
代码部分
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> -->
<link rel="stylesheet" href="./css/swiper.css">
<title>轮播图</title>
</head>
<body>
<main id="main">
<div id="banner-container">
<!-- 左边 -->
<div id="banner-btn-left"></div>
<!-- 内容 -->
<ul id="banner-wrapper" class="transition" style="width:5000px; margin-left:0px;">
<li><a href="javascript:;"><img src="image/carousel_item/carousel-1.jpg"></a></li>
<li><a href="javascript:;"><img src="image/carousel_item/carousel-2.jpg"></a></li>
<li><a href="javascript:;"><img src="image/carousel_item/carousel-3.jpg"></a></li>
<!--注意!最后li个数要比实际图片张数多1,最后一个li里的img是重复第一张li的图片-->
<li><a href="javascript:;"><img src="image/carousel_item/carousel-1.jpg"></a></li>
</ul>
<!-- 轮播圆点选择器 -->
<ul id="banner-contorl">
<!--虽然li个数比实际图片张数多1,但小圆点的个数不必多1-->
<li class="active"></li>
<li></li>
<li></li>
</ul>
<!-- 右边 -->
<div id="banner-btn-right"></div>
</div>
</main>
</body>
<script src="./js/swiper.js"></script>
</html>
css
*{margin:0; padding:0;}
#main{
width:1000px;
margin:200px auto 10px;
}
#banner-container{
width:1000px;
overflow:hidden;
position:relative;
}
#banner-wrapper{
list-style:none;
}
#banner-wrapper.transition{
transition:all .5s linear;
}
#banner-wrapper>li{
width:1000px;
/* 横向排列 */
float:left;
}
#banner-wrapper img{
width:1000px;
}
#banner-contorl{
width:100px;
margin:0 auto;
list-style:none;
position:absolute;
bottom:25px;
left:50%;
margin-left:-50px;
}
#banner-contorl>li{
float:left;
width:10px; height:10px;
background-color:#fff;
border-radius:5px;
margin:0 5px;
cursor:pointer;
}
#banner-contorl>li.active{
background-color:blue;
}
#banner-btn-left,#banner-btn-right{
width:60px;
height:100%;
position:absolute;
top:0;
background-repeat:no-repeat;
background-position:center;
cursor:pointer;
}
#banner-btn-left{
left:20px;
background-image:url(../image/carousel_item/left_ar.png);
}
#banner-btn-right{
right:20px;
background-image:url(../image/carousel_item/right_ar.png);
}
#banner-btn-left:hover,#banner-btn-right:hover{
background-size:40px 70px
}
js
// 1
let i = 0 //用于标记当前第几张
let width = 1000 //每个li固定宽度
let duration = 500 //每次轮播动画持续时间
let count = 3 //控制器li的总个数
// 要移动的ul
let bannerWrapper = document.getElementById("banner-wrapper")
//包含小圆点的列表ul
let bannerContorl = document.getElementById("banner-contorl")
//获取小圆点的元素列表ul里面的li
let lis = bannerContorl.children;
// 2
//创建点击切换事件
let bannerBtnLeft = document.getElementById("banner-btn-left");
let bannerBtnRight = document.getElementById("banner-btn-right");
// 创建允许执行操作控制开关
let canClick = true;
// 3.定时器
let interval = 3000;
let bannerContainer = document.getElementById("banner-container");
// 4
//1.定义函数用于传入参数控制切换具体哪一张轮播图
function moveTo(to) {
// 如果用户没有输入任何值,默认当前项+1
if (to == undefined) {
to = i + 1; //初始i=0
}
// 重置过渡效果(因为后方切换删除了过渡属性)
if (i == 0) {
if (to > i) {
//点击下一张
bannerWrapper.className = "transition";
} else {
//防止i=0在开头,且要继续点上一张
//1.清掉transition属性
bannerWrapper.className = "";
//2.迅速切到最后一项
bannerWrapper.style.marginLeft = -width * count + "px"
//定时器是为了将偷梁换柱操作和加上transition的操作强行分离,让其互不干扰
setTimeout(function () {
moveTo(count - 1); //此时移动到为显示的最后一项(同时替换当前下标)
}, 100);
//阻止继续执行
return;
}
}
//先将表示第几张图片的变量i变为目标位置
i = to;
//操作ul改动位置
bannerWrapper.style.marginLeft = -i * width + "px"
//先清除控制器每一项的class:active属性
for (var li of lis) {
li.className = ""
}
//如果i=最后显示的的图片之后
if (i == count) {
//把i重置为0
i = 0;
//当transition动画播放完之后,才
setTimeout(function () {
bannerWrapper.className = "";//清掉transition属性
bannerWrapper.style.marginLeft = 0;//将整个ul拉回0位置
}, duration)
}
//给当前显示项加上css:active属性
lis[i].className = "active";
}
// 2
bannerBtnLeft.onclick = function () {
move(-1);
}
bannerBtnRight.onclick = function () {
//调用两个按钮公共的移动方法,参数1表示移动到i+1的位置,相当于左移一个
move(1)
}
//两个按钮共用的移动函数,n传入1时,移动到i+1位置,左移。n传入-1时,移动到i-1位置,右移
function move(n) {
if (canClick) {//只有可以单击时
moveTo(i + n);//才调用真正移动ul的方法
canClick = false;//马上把开关关上,禁止再次点击
//只有本地transition动画播放完,才能自动打开开关,点击按钮才有反应。
setTimeout(function () {
canClick = true;
}, duration + 100);
}
}
let timer = setInterval(function () {
//调用主函数
moveTo()
}, interval);
bannerContainer.onmouseover = function () {
clearInterval(timer);
}
bannerContainer.onmouseout = function () {
timer = setInterval(function () {
//调用主函数
moveTo()
}, interval);
}
//4.控制器
//托管事件到父对象
bannerContorl.onclick = function (e) {
if (canClick) {
let li = e.target;
//子节点为li标签
if (li.nodeName == "LI") {
// 且li的className不为active
if (li.className !== "active") {
//遍历lis每一项,直到找到当前项,如果序列对应就不执行跳转
// 此处不能用let,会导致父对象找不到子对象对应的索引
for (var i = 0; i < lis.length; i++) {
if (lis[i] == li) {
break;
}
}
//如果不是相同项,则移动到对应
moveTo(i);
setTimeout(function () {
canClick = true;
}, duration);
}
}
}
}