iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 13
0

成品連結:Custom Video Player程式碼

今天的主題是常見的網站圖片動畫,也就是當滾動至圖片時圖片才會出現,且當圖片離開畫面時會再次隱藏。

透過今天的練習也會更了解 DOM 元素中的屬性操作~

從程式碼可以看到網頁中目前有 5 張圖片,而本次要做的事是當滾動至圖片一半的位置時顯示圖片;而當滾動離開圖片時隱藏圖片,顯示、隱藏的效果透過增加 / 去除 CSS class active 來達成。

設定監聽事件

這裡使用的事件是 scroll,也就是當視窗滾動時觸發 callback function

window.addEventListener('scroll', checkSLide);

設定事件觸發間隔時間

但如果你試著在頁面印出 console.count(e),就會發現從頭滾動到尾會觸發事件超果 100 次,而這可能會對電腦效能造成一定程度的負擔。因此,這裡我們導入 debounce(程式碼請見上方連結),目的是要控制事件觸發的頻率,也就是說至少要間隔一定的時間才會再次觸發事件。
原本的程式碼可以改成:

window.addEventListener('scroll', debounce(checkSLide));

設定 function

首先先把所有圖片存入一個變數

const slideIns = document.querySelectorAll('img.slide-in');

接著開始寫 function 內容

function checkSLide(e) {
    slideIns.forEach(img => {
        // code here
    });
}

顯示圖片

重點來了,要如何偵測目前滾動(視窗底部)是否已到達圖片一半的位置了呢?

首先需要先知道目前滾動到了哪裡,而 window.scrollY 提供了滾動的距離;接著再加上 window.innerHeight 就是視窗底部的位置了。

const slideInAt = window.scrollY + window.innerHeight;

接著圖片中有個屬性 offsetTop 提供了該圖片至網頁頂端的距離(不是視窗喔!),所以當 slideInAt === img.offsetTop 時也就是當視窗底部位置與圖片上緣重疊了;但是由於我們的目的是當滾動至圖片一半時圖片才會出現,所以原本的 slideInAt 需要做一點小調整,也就是扣掉圖片一半的高度

const slideInAt = window.scrollY + window.innerHeight - (img.height / 2);

// 當滾動超過圖片一半時可以顯示圖片
const isImageShown = slideInAt > img.offsetTop;

隱藏圖片

當滾動至圖片一半時可以出現了,接下來要設定當圖片離開畫面時隱藏圖片,也就是說當滾動距離 >(圖片距離網頁頂端距離 + 圖片高度)時

這裡滾動距離不需要加上視窗高度,因為圖片離開會從視窗上緣離去

const imageBottom = img.offsetTop + img.height;

// 當(圖片距離網頁頂端距離 + 圖片高度)> 滾動距離時可以顯示圖片
const isNotScrollPast = window.scrollY < imageBottom;

綜合以上兩點寫入 checkSlide

function checkSLide(e) {
    slideIns.forEach(img => {
        const slideInAt = window.scrollY + window.innerHeight - (img.height / 2);
        // 當滾動超過圖片一半時可以顯示圖片
        const isImageShown = slideInAt > img.offsetTop;
        
        const imageBottom = img.offsetTop + img.height;
        // 當(圖片距離網頁頂端距離 + 圖片高度)> 滾動距離時可以顯示圖片
        const isNotScrollPast = window.scrollY < imageBottom;
        
        if (isImageShown && isNotScrollPast) {
          img.classList.add('active');
        } else {
          img.classList.remove('active');
        }
    });
}

這樣就完成了。或許你會覺得很抽象,尤其是各種不同屬性的相加 / 減到底是怎麼發生的;可以試著印出上面有提到的屬性並試著畫出圖來作比較,或許會讓你更清楚一些。

Reference


上一篇
JS30 Day 12 - Key Sequence Detection
下一篇
Day 14 - JavaScript References VS Copying
系列文
一起挑戰 JavaScript 30 吧!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言