案例--ES6类 渐隐渐现 轮播图

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">&lt;</div>
  <div class="right">&gt;</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;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值