// 淡入淡出的轮播图实现思路:
// 在布局上,用定位将所有的图片重合在一起,将所有的图片的透明度都设置为0, 只让第一张的透明度为1.
// 当自动播放或者点击时,让当前那一张的透明度变为0,后一张的透明度变为1. 再加一个css3的过渡效果即可
/*
步骤:
1. 小圆点的动态设置
2. 自动播放
=》 让当前那一张的透明度变为0,后一张的透明度变为1
3. 点击右箭头:
=》 让当前那一张的透明度变为0,后一张的透明度变为1
4. 点击左箭头:
=》 让当前那一张的透明度变为0,前一张的透明度变为1
5. 点击小圆点:
=》 让当前那一张的透明度变为0,小圆点对应的那一张的透明度变为1
以上,无论是自动播放,还是点击箭头,或者点击小圆点,实际上都是在干切换图片这件事。可以统一封装成函数
// 需要传递参数判断是右箭头,左箭头和小圆点
// 右箭头: true
// 左箭头: false
// 小圆点: 索引
6. 鼠标移入移出效果
*/
/*
类使用小技巧:
// 1. 在构造器函数内部将页面元素的获取挂载到this上
// 2. 将需要在整个类中使用的变量挂载到this上
// 3. 构造器函数在实例化之后,会立即执行,可以将原型方法也挂载this上
*/
class Swiper {
// 构造器函数: 将所有的数据全部挂载到this上
// 目的: 让对应的数据可以在其他原型方法中使用
constructor(id, options) {
this.ele = document.querySelector(id)
this.ulLis = this.ele.querySelectorAll('ul li')
this.olEle = this.ele.querySelector('ol')
this.timer = null // 定时器标识
this.index = 0 // 每张图片的索引
this.options = options || {}
// 1. 动态设置小圆点
this.setDots()
// 2. 自动播放
if (this.options.autoplay) this.autoplay()
// 4. 鼠标移入移出
this.overOut()
// 5. 点击鼠标,切换图片
this.bindEvent()
}
// 1. 动态设置小圆点
setDots() {
// 1.1 获取小圆点的个数
let dotsLength = this.ulLis.length
// 1.2 遍历并动态创建小圆点
for (let i = 0; i < dotsLength; i++) {
// 1.3 动态创建li
let li = document.createElement('li')
// 1.4 添加类名
li.classList.add('item')
// 1.5 默认给第一个小圆点添加选中样式
if (i == 0) li.classList.add('active')
// 1.8 将每个小圆点的索引通过自定义属性挂载到li标签上
li.dataset.idx = i
// 1.6 插入到ol盒子中
this.olEle.appendChild(li)
}
// 1.7 动态设置小圆点盒子的宽度
this.olEle.style.width = (20 + 20) * dotsLength + 'px'
// 1.9 定制图片切换的过渡时间
this.options.duration = this.options.duration || 0.3
for (let i = 0; i < this.ulLis.length; i++) {
this.ulLis[i].style.transition = `all ${this.options.duration}s linear`
}
}
// 2. 自动播放
autoplay() {
// 注意: 这里必须使用箭头函数,不改变定时器函数内部的this指向
this.options.delay = this.options.delay || 2000
this.timer = setInterval(() => {
this.changeImg(true)
}, this.options.delay)
}
// 3. 封装切换图片的函数
changeImg(type) {
// 3.1 让当前那一张的透明度变为0
this.ulLis[this.index].classList.remove('active')
this.olEle.children[this.index].classList.remove('active')
if (type === true) {
// 3.2 获取下一张的索引
this.index++
} else if (type === false) {
this.index--
} else {
this.index = type
}
// 3.4 边界限定
// 3.4.1 如果已经超过最后一张了,需要将索引变为0
if (this.index > this.ulLis.length - 1) this.index = 0
// 3.4.2 如果已经超过第一张了, 需要将索引变为最后一张
if (this.index < 0) this.index = this.ulLis.length - 1
// 3.3 给下一张图片的透明度设置为1
this.ulLis[this.index].classList.add('active')
this.olEle.children[this.index].classList.add('active')
}
// 4. 鼠标移入移出效果
overOut() {
this.ele.addEventListener('mouseover', () => {
clearInterval(this.timer)
})
this.ele.addEventListener('mouseout', () => {
if (this.options.autoplay) this.autoplay()
})
}
// 5. 点击鼠标,切换轮播图
// 利用事件委派实现
bindEvent() {
this.ele.addEventListener('click', (e) => {
// 如果点击的是右箭头
if (e.target.className == 'right') {
this.changeImg(true)
}
// 如果点击的是左箭头
if (e.target.className == 'left') {
this.changeImg(false)
}
// 如果点击的是小圆点
if (e.target.className == 'item') {
this.changeImg(e.target.dataset.idx)
}
})
}
}