JS30 day13 - Slide In on Scroll
作業內容
本日作業是要做出文繞圖的頁面,但圖片會在看到的當下滑進畫面
可以參考這份 CodePen
學到什麼
- JS
-
在這次的教學中, debounce 這個 function 的作用是限制事件最多在某段時間內只能觸發一次 function
window.addEventListener('scroll', debounce(checkSlide))
-
window.scrollY
指的是當下螢幕最上面的 Y 值
-
const isHalfShown = slideInAt > sliderImage.offsetTop
這句表示螢幕的最下方,如果超過圖片的一半為 true ,也可以視為至少看到一半圖片的上半部
const isNotScrollPast = window.scrollY < imageBottom
這句代表螢幕的最上方,還沒超過圖片的最下方,也可以視為還沒往下滑到看不到圖片
所以最後綜合起來就是判斷,至少有往下滑到可以看到圖片的一半,而且還沒往下滑到看不到圖片的高度的話,就會把圖片加上 active 這個 class
1 2 3 4 5 6 7
| 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| 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))
|