JS30 Day 13 筆記


Posted by GL on 2023-05-23

功能

頁面管道到圖片位置的一半時,圖片從兩側滑入,圖片離開視線範圍時,從兩側滑出

Demo

播放

step 1 : 獲取所有的圖片元素

// 獲取所有的圖片元素
const slideImages = document.querySelectorAll('.slide-in')

step 2 : 監聽視窗滾動的事件

由於監聽 scroll 時每次的滾動都會產生事件的觸發,因此使用 debounce 函式,讓間隔 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)
  }
}
// 監聽視窗滾動的事件
window.addEventListener('scroll', debounce(checkSlide))

step 3 : 建立函式 checkSlide

// 建立事件觸發後要執行的函式 checkSlide
function checkSlide(e){
  // 遍歷每一張圖片
  slideImages.forEach(slideImage => {
    // 圖片至少出現 1/ 2 的定位高度 = (捲軸 Y 軸的高度 + 視窗的可見高度) -  1 / 2 的圖片高度
    const slideInAt = (window.scrollY + window.innerHeight) - slideImage.height / 2

    // 圖片的底部定位高度 = 圖片頂點到父層元素的距離 + 圖片高度
    const  imageBottom = slideImage.offsetTop + slideImage.height

    // 是否超過圖片的一半: 至少出現 1 / 2 圖片的位置定位點 - 圖片頂點到父層元素的距離,
    const isHalfShown = slideInAt > slideImage.offsetTop

    // 滾動的位置是否未超過圖片的底部
    const isNotScrollPast = window.scrollY < imageBottom

    // 滾動的位置:如果超過圖片一半且為超過圖片的底部
    if(isHalfShown && isNotScrollPast){
      // 圖片滑入: 增加 active 這個 class name 
      slideImage.classList.add('active')
    }else{
      // 否則圖片滑出: 移除 active 這個 class name 
      slideImage.classList.remove('active')
    }
  })
}

CSS

圖片滑入效果: opacitytransformtransition

/************************
一開始 opacity 設為 0, 
transformX 位置設在向外左右兩邊,
scale 進行縮放 
*************************/
.slide-in {
  opacity: 0;
  transition: all .5s; 
}

.align-left.slide-in {
  transform: translateX(-30%) scale(0.95);
}

.align-right.slide-in {
  transform: translateX(30%) scale(0.95);
}

/************************
捲軸滑倒圖片一半以上的位置時, 
添加 active 這個 class, 
透過 opacity 為 1 與 transformX 為 0%,
讓圖片顯示 
*************************/
.slide-in.active {
  opacity: 1;
  transform: translateX(0%) scale(1);
}

Javascript

Window.scrollY:瀏覽器 Y 軸方向滾動的位置

Window.innerHeight :視窗內的高度

HTMLElement.offsetTop :此元素上方到父元素頂端的距離


參考資料:


#JS 30







Related Posts

第二周筆記 (JS) -4

第二周筆記 (JS) -4

[Note] React: React Router DOM v 6.3.X

[Note] React: React Router DOM v 6.3.X

MTR04 W2 D17 陣列練習題

MTR04 W2 D17 陣列練習題


Comments