#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

【领域展开 08 式】 WordPress 布景主题选择 (彷佛发现无底洞

有时寂寞太沉重,身边彷佛只是观众 Study 後必须套用一下 Tanya 无底洞的歌词,选完使用 W...

应用 LINE Front-end Framework 轻松建立互动 (1)

我们的验证码小帮手现在可以完成的项目有: 对使用者进行身份验证与绑定 判断使用者的讯息,进而回覆对应...

JavaScript条件控制

程序的执行基本上是循序渐进的。程序的执行未必一定是由上到下,一行一行的执行。 有时内容会因为判断,或...

Day.22 Unique Paths

Leetcode #62. Unique Paths 有一个机器人,它只能往右跟往下走,找出可到达终...

Day19有比较有伤害

plotly.js 既然前两天介绍的PivotTable.js是支援plotly.js,那麽我们就...