左右切换轮播图
<body>
<div class="banner">
<ul class="img_box">
<li style="background-color: pink">1</li>
<li style="background-color: orange">2</li>
<li style="background-color: lightgreen">3</li>
<li style="background-color: purple">4</li>
<li style="background-color: skyblue">5</li>
</ul>
<!-- 焦点盒子 -->
<ol></ol>
<!-- 左右切换盒子 -->
<div>
<p class="left"><</p>
<p class="right">></p>
</div>
</div>
<script src="../utils.js"></script>
<script>
/*
左右切换轮播图
1. 布局
=> 可视区域盒子
=> ul > li, 每一个 li 就是一个图片位置, ul 给一个定位
2. 生成焦点
=> 根据图片盒子的子元素数量来生成焦点
=> 调整一下 pointerBox 的宽度
-> 根据焦点的数量来决定宽度
-> 一个焦点是 width 20, margin-left 15
-> 一个焦点 35, 数量 * 35
3. 复制元素
=> 把本身的第一张复制一份, 本身的最后一张复制一份
=> 复制的第一张放在最后, 复制的最后一张放在最前面
=> imgBox 宽度不够了
-> 根据最新的子元素数量设置宽度
=> 重新设置 imgBox 的位置
-> left 赋值为 负的一个可视区域的宽度(即右移)
4. 自动轮播
=> 每间隔一段时间, 运动一段距离
=> 每间隔一段时间: setInterval()
=> 运动一段距离: 封装的 move()
=> 运动多少距离
-> 一次是一个可视区域的宽度
-> 准备一个变量用来记录当前是第几张 图片 index
-> 定时器里面每次 index++
-> 目标位置 -index * 可视区域的宽度
5. 运动结束
=> 判断你到了最后一个 li, 假的第一张的时候
-> 不需要运动, 瞬间定位回真的第一张
-> 假的第一张实际上就是最后一个 li
-> 最后一个 li 的索引就是 length - 1
=> 改变焦点位置
-> 所有的 焦点 都没有 active 类名
-> 只给当前索引配套的焦点加上 active 类名
-> 焦点和谁配套
-> index === 1 的时候显示 第 1 张 第 0 个焦点
-> index === 2 的时候显示 第 2 张 第 1 个焦点
-> index === 3 的时候显示 第 3 张 第 2 个焦点
6. 移入移出事件
=> 移入 banner 区域的时候, 停止定时器
-> 要么是要点击左右切换
-> 要么是要点击焦点按钮
-> 要么是要观察图片
=> 移出 banner 区域的时候, 再次自动轮播
7. 点击事件
=> 焦点, 左右切换
=> 焦点是渲染的
=> 事件委托, banner
=> 右按钮切换下一张
-> index++
-> 调用 move 函数切换到下一张
=> 左按钮切换上一张
-> index--
-> 到了第 0 张的时候, 出现问题
-> 因为我们的运动结束, 只判断了 最后一张的时候瞬间定位到第二张
-> 还需要判断到第 0 张的时候, 瞬间定位到 倒数第二张
8. 解决鬼畜
=> 为什么会出现?
-> 当你点击按钮的时候, 会切换到下一张
-> 在切换到下一张的时候, 需要时间, 假设 500ms
-> 500ms 以后换到下一张, index 是否拉回到第一张, 需要在 500ms 以后进行判断
-> 当你在 500ms 之内的时候, 多次点击, 没有经历过判断
-> index 一直在 ++
-> 原因: 没有等到运动结束就执行下一次切换
=> 解决办法?
-> 开关
-> 当它要切换到下一张的时候, 开始切换的时候, 把开关关闭
-> 等到切换完毕以后, 再把开关打开
-> 在每一个事件里面进行判断, 如果开关是关闭状态
-> 那么不进行任何操作
=> 开关
-> 初始值定义成什么? false, 依次都点击不了, 设为 true
-> 什么时候开? 当运动结束, 你的焦点和 index 都设置好了以后开启
-> 什么时候关? 各种事件里面关闭
-> 什么位置判断? 各种事件里面判断
=> 问题2:
-> 因为当你的浏览器最小化
-> 或者说你离开页面的时候
-> 定时器是继续走着的
-> 但是 DOM 是不动的
=> 解决问题2:
-> 离开当前页面的时候, 关闭定时器
-> 回到当前页面的时候, 再次开启定时器
-> document.onvisibilitychange 事件
+ 离开标签页和回到标签页的时候触发
*/
// 0. 获取元素
// 0-1. 获取承载图片的盒子
const imgBox = document.querySelector('.banner > ul')
// 0-2. 获取承载焦点的盒子
const pointBox = document.querySelector('.banner > ol')
// 0-3. 获取可视区域的盒子
const banner = document.querySelector('.banner')
// 1. 准备变量
// 1-1. 准备一个可视区域的宽度
const banner_width = banner.clientWidth
// 1-2. 准备一个变量记录定时器返回值
let timer = 0
// 1-3. 准备一个变量记录是第几张
let index = 1
// 1-4. 准备一个变量当作开关
let flag = true
// 2. 生成焦点
setPoint()
function setPoint(){
// 2-1. 获取要生成多少个焦点
const num = imgBox.children.length
// 2-2. 生成若干个 li 放在 ol 里面
// 创建文档碎片
const frg = document.createDocumentFragment()
for(let i = 0; i < num