iT邦幫忙

1

JS30 Day 13 - Slide in on Scroll學習筆記

  • 分享至 

  • xImage
  •  

今天的功能是當往下滾動頁面,會在對應的地方顯示圖片。

https://ithelp.ithome.com.tw/upload/images/20200624/201261825pzPyFer8W.png

首先,獲取全部圖片,並將視窗增加滾動事件。
而作者有寫一個debounce的函數,我們將滾動的事件函數當作參數放進debounce,用意在下一段說明。


    // 獲取全部圖片
    let images = document.querySelectorAll('.site-wrap img');

    // 滾軸滾動會觸發(連續)
    // 將滾動函數作為參數包進debounce裡
    window.addEventListener('scroll', debounce(scrollHandler));

由於滾動事件會連續觸發,會影響效能,所以我們可以利用debounce,去設定每個事件觸發之間的間隔,讓其不會連續觸發。

    // func為我們要操作的函數,wait為延遲時間,immediate為第一次是否要立即執行
    function debounce(func, wait = 20, immediate = true) {
      var timeout;
      return function () {
        var context = this,
          // 能獲取所有參數並以陣列型式返回
          args = arguments;
        var later = function () {
          timeout = null;
          // apply與call功能一樣差別在於傳遞參數方式
          if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
      };
    }

在滾動函數部分,首先我們要獲取當前視窗頂部的y座標,利用window.scrollY即可獲取,反之底部y座標則是在當前頂部的地方,再加上當前視窗的高度(window.innerHeight)

https://ithelp.ithome.com.tw/upload/images/20200624/20126182i7lHqFhy4D.png

而在來就是使圖片顯示。

第一個為只要圖片的頭部觸碰到視窗的底線,就會顯示圖片,而我們需要利用offsetTop去獲取圖片離頂部的高度,當其高度小於底部就會顯示圖片。

第二個為只要圖片的中間觸碰到視窗的底線,這也是這此次我們所選擇的,而大多時候也是採用在中間的做法,會使User有更加的體驗,而我們除了需要利用offsetTop去獲取圖片離頂部的高度,還要加上圖片本身一半的高度(Height/2),這樣就可獲取圖片中間距離底部的距離,當其高度小於底部就會顯示圖片。

第三個為只要圖片的底部觸碰到視窗的底線,就會顯示圖片,與第二個不同的在於不用除以2,而是要加上圖片本身的高度(Height),這樣就可獲取圖片底部距離底部的距離,當其高度小於底部就會顯示圖片。


    function scrollHandler() {
      // 視窗頂部y座標(也就是視窗的最上面的線)
      let windowTop = window.scrollY;
      // 視窗底部y座標(也就是視窗的最下面的線)
      let windowBottom = windowTop + window.innerHeight;
      console.log(windowTop, windowBottom);

      // 讓圖片active

      // 1.只要圖片頭部進到畫面(超過底線)就進來
      // images.forEach((img) => {
      // offsetTop為圖片離頂部的距離
      //   if (img.offsetTop < windowBottom) {
      //     img.classList.add('active');
      //   }
      // });

      // 2.只要圖片中間進到畫面(超過底線)就進來,一般都是用中間
      images.forEach((img) => {
        let imgMiddle = img.offsetTop + img.height / 2;
        // offsetTop再加上圖片一半的高度
        // 做優化(圖片中間位置要小於視窗底部且大於視窗頂部)
        if (imgMiddle < windowBottom && imgMiddle > windowTop) {
          img.classList.add('active');
        } else {
          img.classList.remove('active');
        }
      });

      // 3.只要圖片尾部進到畫面(超過底線)就進來
      // images.forEach((img) => {
      //   // offsetTop再加上圖片本身高度
      //   if (img.offsetTop + img.height < windowBottom) {
      //     img.classList.add('active');
      //   }
      // });
    }

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言