前端原生js*轮播图*案例面向过程+详解*

js源码 (html css 参考js类语法面向对象实现轮播图)

/*
  轮播图js代码
*/
// 1. 获取元素
// 1-1. 获取承载图片的 imgBox
const imgBox = document.querySelector('.imgBox')
// 1-2. 可视窗口的盒子
const banner = document.querySelector('.banner')
// 1-3. 承载焦点的盒子 pointBox
const pointBox = document.querySelector('.pointBox')
// 2. 准备变量
// 2-1. 准备一个变量表示第几张
let index = 1
// 2-2. 准备一个变量记录可视窗口的宽度
// 元素.clientWidth 获取到的是元素 内容 + padding 区域的尺寸
const banner_width = banner.clientWidth
// 2-3. 准备一个变量接受定时器返回值
let timerId = 0
// 2-4. 准备一个变量表示开关
let flag = true
// 3. 代码逻辑
// 3-1. 复制元素
copyEle()

function copyEle() {
  // 1. 克隆 第一个 和 最后一个 子元素
  const first = imgBox.firstElementChild.cloneNode(true)
  const last = imgBox.lastElementChild.cloneNode(true)
  // 2. 插入元素
  // 把第一个插入到最后
  imgBox.appendChild(first)
  // 把最后一个插入到最前
  imgBox.insertBefore(last, imgBox.firstElementChild)
  // 3. 调整 imgBox 的宽度
  imgBox.style.width = imgBox.children.length * 100 + '%'
  // 4. 调整 imgBox 的 left 的值
  imgBox.style.left = -index * banner_width + 'px'
}
// 3-2. 设置焦点
setPoint()
function setPoint() {
  // 1. 拿到需要生成多少个焦点按钮的数量
  const pointNum = imgBox.children.length - 2
  // 2. 准备一个筐
  const frg = document.createDocumentFragment()
  // 3. 循环遍历生成 焦点li 放在 frg 内部
  for (let i = 0; i < pointNum; i++) {
    // 生成 li
    const li = document.createElement('li')
    // 要默认给第一个加上 active 类名
    if (i === 0) li.classList.add('active')
    // 给每一个 li 添加一个 point 的类名
    li.classList.add('point')
    // 给每一个 li 添加一个 自定义属性
    li.dataset.pointIndex = i
    // 放在筐里面
    frg.appendChild(li)
  }
  // 4. 把 frg 放在 pointBox 内部
  pointBox.appendChild(frg)
  // 5. 调整一下 pointBox 的宽度
  pointBox.style.width = pointNum * (20 + 10) + 'px'
}
// 3-3. 自动轮播
autoPlay()
function autoPlay() {
  // 1. 开启定时器
  timerId = setInterval(() => {
    // 2. 调整 index
    index++
    // 3. 让 imgBox 运动到第 index 张的位置
    // 调用 move 函数让 imgBox 运动
    move(imgBox, {
      left: -index * banner_width
    }, moveEnd)
  }, 2000)
}
// 3-4. 运动结束
function moveEnd() {
  // 1. 向前进行瞬间定位
  // 我怎么知道来到真的最后一张了
  // 有 x 张图片, 最后一张的索引是 x-1
  if (index === imgBox.children.length - 1) {
    // 瞬间定位到真的第一张
    index = 1
    // 不需要运动, 需要瞬间定位
    imgBox.style.left = -index * banner_width + 'px'
  }
  // 2. 向后进行瞬间定位
  // 你怎么知道来到的假的最后一张
  if (index === 0) {
    // 瞬间定位到真的最后一张
    // 真的最后一张索引 length - 2
    index = imgBox.children.length - 2
    // 不需要运动函数, 瞬间进行定位
    imgBox.style.left = -index * banner_width + 'px'
  }
  // 3. 焦点配套
  // 给所有焦点去掉类名
  for (let i = 0; i < pointBox.children.length; i++) {
    pointBox.children[i].classList.remove('active')
  }
  // 给指定的那一个添加 active 类名
  // 指定: index - 1
  pointBox.children[index - 1].classList.add('active')
  // 8-3. 再次开启开关
  // 代码执行到这里, 表示一张图片切换完毕了
  // 该瞬间定位的已经调整完毕了
  // 该切换的焦点也切换完毕了
  // 可以正常去切换下一张了
  flag = true
}
// 3-5. 移入移出
overOut()
function overOut() {
  // 1. 移入停止自动轮播
  banner.addEventListener('mouseover', () => clearInterval(timerId))
  // 2. 移出再次开启自动轮播
  banner.addEventListener('mouseout', () => autoPlay())
}
// 3-6. 绑定事件
bindEvent()
function bindEvent() {
  // 1. 给 banner 盒子绑定点击事件
  banner.addEventListener('click', e => {
    // 处理事件对象兼容
    e = e || window.event
    // 处理事件目标兼容
    // 事件目标: 准确触发事件的那个元素
    const target = e.target || e.srcElement
    // 2. 判断你准确的点击的是哪一个元素
    // 2-1. 判断左按钮
    if (target.className === 'prevBtn') {
      if (flag === false) return
      flag = false
      // 操作 index
      index--
      // 使用 move 函数
      move(imgBox, {
        left: -index * banner_width
      }, moveEnd)
    }
    // 2-2. 判断右按钮
    if (target.className === 'nextBtn') {
      // 8-1. 判断开关如果是关闭的, 那么什么都不做了
      if (flag === false) return
      // 8-2. 关闭开关
      // 代码能执行到这里, 表示开关是开启状态
      // 把开关关闭
      flag = false
      // 操作 index
      index++
      // 使用 move 函数
      move(imgBox, {
        left: -index * banner_width
      }, moveEnd)
    }
    // 2-3. 判断焦点按钮
    if (target.className === 'point') {
      if (flag === false) return
      flag = false
      // 给 index 赋值为焦点的 索引 + 1
      index = target.dataset.pointIndex - 0 + 1
      // 使用 move 函数
      move(imgBox, {
        left: -index * banner_width
      }, moveEnd)
    }
  })
}
// 3-7. 解决离开页面抖动
changeTab()
function changeTab() {
  // 1. 给 document 绑定一个 visibilitychange 事件
  document.addEventListener('visibilitychange', () => {
    // 2. 通过可视程度决定如何操作
    if (document.visibilityState === 'hidden') clearInterval(timerId)
    if (document.visibilityState === 'visible') autoPlay()
  })
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值