iT邦幫忙

2022 iThome 鐵人賽

DAY 13
0

13 - Slide in on Scroll

tags: JavaScript30

專案簡介

第十三天的目標是幫一段文章加入章節圖片的滑入滑出特效

課程影片:JS30 13
導讀影片:Alex

初始文件

Github 檔案位置:13 - Slide in on Scroll

網頁一開始的樣子如下,空白的就是我們要做圖片滑入的地方

可以先去看看 最後的成品

正式製作

流程

今天的專案要求大概如下

  1. 監聽右方畫面滾動條的位置,以此加上滑入動畫
  2. 以 debounce 降低效能的浪費

監聽右方畫面滾動條的位置,以此加上滑入動畫

首先先監聽 scroll 滾動事件,然後在觸發事件時輸出 window.scrollY 目前的滾動軸 Y 座標

function scrollHandler() {
  console.log(window.scrollY);
}

window.addEventListener('scroll', scrollHandler);

接下來選取文章的所有圖片,我們希望圖片出現在可視範圍內時有滑入特效,離開時有滑出特效,因此需要算出可視範圍的上下界
下界的算法就是上界加上 window.innerHeight,等同於最高點加上可視視窗高度等於下界

備註:進度條的 Y 軸是相反的,越往下滑 Y 軸數值越大

然後我們做的事情就相對單純了,在圖片的中座標出現在可視範圍內就加入 active 離開就移除

圖片頂座標的取法是 image.offsetTop 中座標只要加上一半的高度就有囉 owo

let images = document.querySelectorAll(".slide-in");
    
function scrollHandler() {
  // console.log(window.scrollY);
  let windowTop = window.scrollY;
  let windowBottom = windowTop + window.innerHeight;
  // console.log(windowTop);
  images.forEach(image => {
    let imgTop = image.offsetTop;
    let imgMid = imgTop + image.height / 2;
    if(imgMid > windowTop && imgMid < windowBottom){
      image.classList.add('active');
    }
    else{
      image.classList.remove('active');
    }
  })
}

window.addEventListener('scroll', scrollHandler);

到這裡就做完今天主要的功能啦~

以 debounce 降低效能的浪費

由於在閱讀一篇文章時,滾動的事件會非常頻繁的觸發,因此會希望可以控制執行事件的頻率,使每次的事件要停留一段時間才會被真正的執行

這段程式碼乍看之下有些複雜,但實際上的運行邏輯如下

  1. 如果觸發滾動事件時,沒有正在等待運行的計時器,就直接運行 scrollHandler() 函式
    • apply() 是用來傳遞 this 以及呼叫參數的函式
  2. 清空目前的計時器,設定新的計時器(不執行連續觸發的時間差,小於延遲的事件)
function debounce(func, wait = 10, 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);
  };
}

在使用這個方式處理滾動事件,可以發現 window.scrollY 座標中間的跨度變大了許多,並且不會出現相近的值一直出現的情況

完成結果圖

最後的成品

結語

以上是第十三天的製作紀錄,如有錯誤或不足的地方還請多多指教 >.<

Vanilla JavaScript Slide In on Scroll - #JavaScript30 13/30
[ Alex 宅幹嘛 ] 深入淺出 Javascript30 快速導覽 | Day 13:Slide in on Scroll
MDN Web Docs


上一篇
JS30 -> 12 - Key Sequence Detection
下一篇
JS30 -> 14 - JavaScript References VS Copying
系列文
剛接觸前端一個月的小白 - JavaScript30 挑戰筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言