Anthony Chao

JS30 day13 Slide In on Scroll

#Javascript

JS30 day13 - Slide In on Scroll

作業內容

本日作業是要做出文繞圖的頁面,但圖片會在看到的當下滑進畫面 可以參考這份 CodePen

學到什麼

  • JS
    1. 在這次的教學中, debounce 這個 function 的作用是限制事件最多在某段時間內只能觸發一次 function window.addEventListener('scroll', debounce(checkSlide))

    2. window.scrollY 指的是當下螢幕最上面的 Y 值

    3. const isHalfShown = slideInAt > sliderImage.offsetTop 這句表示螢幕的最下方,如果超過圖片的一半為 true ,也可以視為至少看到一半圖片的上半部 const isNotScrollPast = window.scrollY < imageBottom 這句代表螢幕的最上方,還沒超過圖片的最下方,也可以視為還沒往下滑到看不到圖片 所以最後綜合起來就是判斷,至少有往下滑到可以看到圖片的一半,而且還沒往下滑到看不到圖片的高度的話,就會把圖片加上 active 這個 class

    const isHalfShown = slideInAt > sliderImage.offsetTop
    const isNotScrollPast = window.scrollY < imageBottom
    if(isHalfShown && isNotScrollPast){
      sliderImage.classList.add("active")
    }else{
      sliderImage.classList.remove("active")
    }

參考資料: https://github.com/wesbos/JavaScript30

code 內容: CSS:

html {
  box-sizing: border-box;
  background: #ffc600;
  font-family: 'helvetica neue';
  font-size: 20px;
  font-weight: 200;
}

body {
  margin: 0;
}

*, *:before, *:after {
  box-sizing: inherit;
}

h1 {
  margin-top: 0;
}

.site-wrap {
  max-width: 700px;
  margin: 100px auto;
  background: white;
  padding: 40px;
  text-align: justify;
}

.align-left {
  float: left;
  margin-right: 20px;
}

.align-right {
  float: right;
  margin-left: 20px;
}

.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);
}

.slide-in.active {
  opacity: 1;
  transform: translateX(0%) scale(1);
}

JS:

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);
  };
}

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 isNotScrollPast = window.scrollY < imageBottom
    if(isHalfShown && isNotScrollPast){
      sliderImage.classList.add("active")
    }else{
      sliderImage.classList.remove("active")
    }
  })
  
}
window.addEventListener('scroll', debounce(checkSlide))