ES6 的类语法*书写构造函数
属性:
1. 范围元素
2. imgBox
3. pointBox
4. index: 表示当前第几张, 默认应该是 0
5. timer: 定时器的返回值
方法:
1. 设置焦点
2. 切换一张
3. 自动轮播
4. 移入移出
5. 点击事件: 事件委托
第二套思路
1. 右按钮, 当前 这个取消类名, 下一张 添加类名
2. 左按钮, 当前 这个取消类名, 上一张 添加类名
3. 焦点按钮 当前 这个取消类名, 某一张 添加类名
+ 合并成 当前 这个取消类名, 某一张(++, --, 索引) 添加类名
4. 自动轮播, 每间隔一段时间, 执行一遍 右按钮 的逻辑
class Banner {
constructor (select) {
// 范围元素
this.ele = document.querySelector(select)
// imgBox
this.imgBox = this.ele.querySelector('.imgBox')
// pointBox
this.pointBox = this.ele.querySelector('.pointBox')
// 表示索引的变量
this.index = 0
// 定时器的返回值
this.timer = 0
// 直接调用启动器
this.init()
}
// 0. 准备一个启动器
init () {
this.setPoint()
this.autoPlay()
this.overOut()
this.bindEvent()
}
// 1. 设置焦点
/*
1-1. 拿到需要生成多少个焦点
=> 需要根据 imgBox 内子元素的数量
1-2. 循环生成 li
=> 把生成的 li 放在 pointBox 内部
1-3. 调整一下 pointBox 的宽度
*/
setPoint () {
// 1-1. 拿到需要生成多少个焦点
const n = this.imgBox.children.length
// 1-2. 循环生成焦点
for (let i = 0; i < n; i++) {
const li = document.createElement('li')
// 默认第一个 li 有 active 类名
if (i === 0) li.classList.add('active')
// 每一个 li 添加一个类名
li.classList.add('point')
// 把索引以自定义属性的方式写在标签身上
li.dataset.point = i
this.pointBox.appendChild(li)
}
// 1-3. 调整一下宽度
this.pointBox.style.width = (10 + 5) * n + 'px'
}
// 2. 切换一张
/*
如何切换一张
2-1. 让当前这一张取消 active 类名
=> this.imgBox 的所有子元素中, 索引为 index 的那一张
=> 因为 图片 和 焦点 的索引是完全配套的, 顺便连焦点一起取消类名
2-2. 修改 this.index 的值
=> 需要让 this.index 变成我接下来需要显示的那一张的索引
=> 给 changeOne 定义一个参数
-> 如果 type 为 true, 我就 ++
-> 如果 type 为 false, 我就 --
-> 如果 type 为 数字, 那么就是一个索引
2-3. 让 this.index 表示的这一张添加 active 类名
*/
changeOne (type) {
// 2-1. 取消 active 类名
this.imgBox.children[this.index].classList.remove('active')
this.pointBox.children[this.index].classList.remove('active')
// 2-2. 根据 type 来决定修改 this.index 的值
if (type === true) {
this.index++
} else if (type === false) {
this.index--
} else {
this.index = type
}
// 判断一下边界
if (this.index >= this.imgBox.children.length) this.index = 0
if (this.index < 0) this.index = this.imgBox.children.length - 1
// 2-3. 添加 active 类名
this.imgBox.children[this.index].classList.add('active')
this.pointBox.children[this.index].classList.add('active')
}
// 3. 自动轮播
/*
每间隔一段时间, 切换下一张
+ 如何切换下一张, 调用 this.changeOne, 传递参数为 true
*/
autoPlay () {
this.timer = setInterval(() => this.changeOne(true), 2000)
}
// 4. 移入移出
overOut () {
this.ele.addEventListener('mouseover', () => clearInterval(this.timer))
this.ele.addEventListener('mouseout', () => this.autoPlay())
}
// 5. 点击事件
bindEvent () {
this.ele.addEventListener('click', e => {
// 处理事件对象兼容
e = e || window.event
// 处理事件目标兼容
const target = e.target || e.srcElement
// 判断左按钮
if (target.className === 'left') this.changeOne(false)
// 判断右按钮
if (target.className === 'right') this.changeOne(true)
// 判断某一张
if (target.className === 'point') this.changeOne(target.dataset.point - 0)
})
}
}
<!-- 结构布局 -->
<div class="banner" id="banner">
<ul class="imgBox">
<li class="active" style="background-color: skyblue;">1</li>
<li style="background-color: purple;">2</li>
<li style="background-color: yellow;">3</li>
<li style="background-color: hotpink;">4</li>
<li style="background-color: orange;">5</li>
</ul>
<ol class="pointBox"></ol>
<div class="left"><</div>
<div class="right">></div>
</div>
<script src="./banner.js"></script>
<script>
// 为了实现轮播图
const b = new Banner('#banner')
console.log(b)
</script>
* {
margin: 0;
padding: 0;
}
ol, ul, li {
list-style: none;
}
img {
width: 100%;
height: 100%;
display: block;
}
.banner {
width: 600px;
height: 400px;
border: 10px solid pink;
margin: 50px auto;
position: relative;
}
.banner > .imgBox {
position: relative;
width: 100%;
height: 100%;
}
.banner > .imgBox > li {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
transition: opacity .5s linear;
opacity: 0;
font-size: 100px;
font-weight: 700;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
}
.banner > .imgBox > li.active {
opacity: 1;
}
.banner > .pointBox {
width: 100px;
height: 15px;
background-color: rgba(0, 0, 0, .5);
position: absolute;
left: 30px;
bottom: 30px;
border-radius: 15px;
display: flex;
justify-content: space-evenly;
align-items: center;
}
.banner > .pointBox > li {
width: 10px;
height: 10px;
background-color: #fff;
border-radius: 50%;
cursor: pointer;
}
.banner > .pointBox > li.active {
background-color: red;
}
.banner:hover > div {
display: flex;
}
.banner > div {
width: 30px;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 50%;
transform: translateY(-50%);
background-color: rgba(0, 0, 0, .3);
color: #fff;
font-size: 22px;
cursor: pointer;
display: none;
}
.banner > div:hover {
background-color: rgba(0, 0, 0, .5);
}
.banner > div.left {
left: 0;
border-radius: 0 15px 15px 0;
}
.banner > div.right {
right: 0;
border-radius: 15px 0 0 15px;
}