JavaScript30第十三天的目標是幫一段文章加入章節圖片的滑入滑出特效
Github 檔案位置:13 - Slide in on Scroll
網頁一開始的樣子如下,空白的就是我們要做圖片滑入的地方
可以先去看看 最後的成品
今天的專案要求大概如下
首先先監聽 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);
到這裡就做完今天主要的功能啦~
由於在閱讀一篇文章時,滾動的事件會非常頻繁的觸發,因此會希望可以控制執行事件的頻率,使每次的事件要停留一段時間才會被真正的執行
這段程式碼乍看之下有些複雜,但實際上的運行邏輯如下
scrollHandler() 函式
this 以及呼叫參數的函式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