#6. Scroll Animation(原生JS版), #7. Progress Steps(原生JS版)

Scroll Animation 卡片滑动载入效果(原生JS版)

CodePen: https://codepen.io/zyrxdkoz/pen/dyROrLB

实作逻辑

javacript

// 选取所有.box
const boxes = document.querySelectorAll('.box')
window.addEventListener('scroll', checkBoxes)

checkBoxes()

function checkBoxes () {
  // 取得启动点,取在视窗高度的五分之一位置
  const triggerBottom = window.innerHeight / 5 * 4

  // 用forEach处理每个box
  boxes.forEach(box => {
    // 运用getBoundingClientRect方法找出viewport与element的距离
    const boxTop = box.getBoundingClientRect().top
    
    // 如boxTop比启动点小,就加入show选择器否则取消
    if (boxTop < triggerBottom) {
      box.classList.add('show')
    } else {
      box.classList.remove('show')
    }
  })
}

CSS部分(节录)

.box {
  background-color: steelblue;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 400px;
  height: 200px;
  margin: 10px;
  border-radius: 10px;
  box-shadow: 2px 4px 5px rgba(0, 0, 0, 0.3);
  
  // 预设位置是左移400%
  transform: translateX(400%);
  transition: transform 0.4s ease;
  
  // 顺序为奇数的box项目,则是右移400%
  &:nth-of-type(even) {
    transform: translateX(-400%);
  }
  h2 {
    font-size: 45px;
  }
  &.show {
    // 加入show选择器时,返回到画面中央
    transform: translateX(0);
  }

Progress Steps 进度条按钮(原生JS版)

CodePen: https://codepen.io/zyrxdkoz/pen/rNwWgrM

实作逻辑

javacript

const prev = document.getElementById('prev')
const next = document.getElementById('next')
const circles = document.querySelectorAll('.circle')
const progress = document.getElementById('progress')
const actives = document.querySelectorAll('.active')

let currentActive = 1

// next按钮行为
next.addEventListener('click', () => {
  currentActive++
  // 让currentActive数值与circles.length同步
  if (currentActive > circles.length) { currentActive = circles.length }
  update()
})

// prev按钮行为
prev.addEventListener('click', () => {
  currentActive--
  // 让currentActive数值与circles.length同步
  if (currentActive < 1) { currentActive = 1 }
  update()
})

function update () {
  // 用currentActive逐一比对每个circle的序数,作出相应行为
  circles.forEach((circle, idx) => {
    if (idx < currentActive) {
      circle.classList.add('active')
    } else {
      circle.classList.remove('active')
    }
  })
  const actives = document.querySelectorAll('.active')
  
  // 计算progress的长度(预设为0%)
  // 初始值:分母是4 - 1,分子是1 - 1
  // 第一次按next: 分母是4 - 1,分子是2 - 1,相当於33%
  // 第二次按next: 分母是4 - 1,分子是3 - 1,相当於66%
  progress.style.width = (actives.length - 1) / (circles.length - 1) * 100 + '%'
  
  // 判断何时要将按钮做disable处理
  if (currentActive === 1) {
    prev.disabled = true
  } else if (currentActive === circles.length) {
    next.disabled = true
  } else {
    prev.disabled = false
    next.disabled = false
  }
}

明日任务

  1. Q&A Section (Vue版本)
  2. Button Ripple Effect (JS原生版)

<<:  Day7 - 读 Concurrency is not Parallelism - Rob Pike (二)

>>:  Day7 风生水起,观元辰宫的木-2

前端工程学习日记第7天

#作业:设计一个三栏式版面,具有表头表尾的版面吧! charter 2. boxsizing方便不用...

Day15 跟着官方文件学习Laravel-实作API(二)

今天我们要继续实作store,昨天我们已经完成service了,今天应该不难。 public fun...

用React刻自己的投资Dashboard Day9 - useEffect hook

tags: 2021铁人赛 React 既上一篇介绍完useState hook後,本篇就来介绍Da...

RESTful API

用户或资源所有者向身份提供者而不是联合系统中的资源或 API 服务器进行身份验证。身份提供者向客户端...

D18 -「脉冲×宽度×调变」:建立控制组件

再来就是实际建立透过 select 选择的脚位,并建立相关 Firmata 功能。 建立 PWM 控...