[JavaScript 30]Day13-Slide In on Scroll

Ivy Ho
IvyCodeFive
Published in
7 min readJun 5, 2022

今天要練習用純 JS,監聽 scroll 事件、計算高度,以及控制 CSS 樣式,做出類似 AOS 套件裡 fade-rightfade-left 的動畫效果!

功能需求

  1. 當頁面滾動到超過圖片高度一半的位置,讓圖片由左或由右淡入顯示。
  2. 由頁面下方往回滾動至上方,也要有一樣的效果。

學習重點

觀察範例檔案初始狀態

html :

範例中總共有 5 個圖片進入點,預設有 5 張圖片,都有 .slide-in 這個 class 名稱,搭配 .align-right.align-left

例如 :

CSS :

與圖片淡入效果相關的 CSS 都預先寫好了

  • 利用 float 讓圖片在文章中有文繞圖的效果
  • 先預設 opacity 為 0,讓圖片先隱藏
  • 加入 transition 設定,等等控制圖片出現才會有漸變效果
  • 利用 transform 的 translateX 先將圖片往外位移, 以及 scale 設置,讓圖片小一些。
  • 之後再利用 JS 判斷條件,加上 .active 這個 class,將 opacity 設回 1,translateX 將圖片拉回原位,scale 讓圖片變回原來大小,就可以達成我們要的淡入動畫效果。

JS :

已預先放了一段 debounce 程式碼,常用來防止事件頻繁被觸發。

在此範例中,可用來避免監聽 scroll event 時,在連續滾動的情況下,頻繁觸發事件,造成頁面效能負擔。

在第一行 wait=20 的參數位置,可以設定要延遲的毫秒數。

function debounce(func, wait = 20, immediate = true) {  var timeout;  return function() {    var context = this, args = arguments;    var later = function() {      timeout = null;      if (!immediate) func.apply(context, args);    };    var callNow = immediate && !timeout;    clearTimeout(timeout);    timeout = setTimeout(later, wait);    if (callNow) func.apply(context, args);  };}

(最後完成的完整 JS 程式碼,以及檔案下載、課程連結,將放在最下方)

解決思路

一、對 window 監聽 scroll event,觸發 checkSlide 事件

二、抓到判斷圖片滑入的基準點

三、計算出圖片最底部距離頁面最上方的高度值

四、判斷如果符合條件,就在圖片加上 .active 這個 class 以達到淡入動畫效果

一、對 window 監聽 scroll event,觸發 checkSlide 事件

  • 為了防止事件被頻繁觸發,影響頁面效能,所以將事件利用 debounce 函式做處理。

二、抓到判斷圖片滑入的基準點

抓到當前視窗最底位置的高度值(依滾動的情況不同,此高度值會動態變化),減去圖片高度的一半

  • 遍歷每一張圖片
  • 當前視窗最底位置的高度值 = window.scrollY(已捲動的高度) + window.innerHeight(視窗高度)
  • 圖片高度的一半 = sliderImage.height / 2
  • slideInAt = 當前頁面最底位置的高度值 - 圖片高度的一半

三、計算出圖片最底部距離頁面最上方的高度值

  • 利用 sliderImage.offsetTop (圖片距離頁面最上方的高度),加上 sliderImage.height (圖片本身高度),來獲得圖片最底部距離頁面最上方的高度值 imageBottom

四、判斷如果符合條件,就在圖片加上 .active 這個 class 以達到淡入動畫效果

  • 將判斷條件先存取至變數如 isHalfShown、isNotScrolledPast,可增加程式碼的可讀性,避免判斷式過長,難以閱讀。
  • isHalfShown : 當剛剛設定的滑入基準點 slideInAt 高度值,大於圖片距離頁面最上方的高度距離(此時正是頁面滾動到超過圖片高度一半的位置)
  • isNotScrolledPast : 圖片最底部還沒消失在視窗畫面
  • 同時符合以上兩個條件,就在該圖片加上 .active 這個 class ,不符合則移除 .active

到這邊就完成了今天要練習的圖片淡入效果~

完整 JS 程式碼

const sliderImages = document.querySelectorAll('.slide-in');function checkSlide(e) {  sliderImages.forEach(sliderImage => {    const slideInAt = (window.scrollY + window.innerHeight) - sliderImage.height / 2;    const imageBottom = sliderImage.offsetTop + sliderImage.height;    const isHalfShown = slideInAt > sliderImage.offsetTop;    const isNotScrolledPast = window.scrollY < imageBottom;    if(isHalfShown && isNotScrolledPast) {      sliderImage.classList.add('active');    }else {      sliderImage.classList.remove('active');    }  })}window.addEventListener('scroll', debounce(checkSlide));

--

--

Ivy Ho
IvyCodeFive

"You don't have to be great to start, but you have to start to be great."