JS30 day13 Slide In on Scroll

Posted by Anthony Chao on 2019-11-13

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

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




prevent_hack