iT邦幫忙

2024 iThome 鐵人賽

DAY 24
0
JavaScript

可愛又迷人的 Web API系列 第 24

Day24. 深入了解 Intersection Observer API 與其應用 II

  • 分享至 

  • xImage
  •  

除了前面一在提到的 Lazy Load 和 Infinity Scroll 外,還有其他好玩的應用,簡單跟大家分享幾個我常在用的

根據使用者行為觸發事件

我們可以用 Intersection Observer 來觀察使用者是否看了頁面中的某些重要內容,例如促銷訊息、新功能、教學 ... 等,但如果只是單純記錄,其實用 Google Analytics 的事件也比較方便,所以我通常是用來判斷當使用者看了某些內容後,我們要觸發特定的事件,讓使用者有耳目一新的感覺。

功能實作起來不難,唯一要注意的是,當使用者看過這個內容後,就可以停止觀察該元素,避免重複觸發,讓使用者覺得很煩 XXD。所以這中間的互動要掌握得好,既要讓使用者覺得貼心,又不要覺得一直備受打擾。

const specialContent = document.getElementById('special-content');

const logUserEngagement = (entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      console.log('使用者正在查看特定內容');
      // 停止觀察,避免重複觸發
      observer.unobserve(entry.target);
    }
  });
};

const observer = new IntersectionObserver(logUserEngagement, { threshold: 1.0 });
observer.observe(specialContent);

根據滑動的頁面修改選單顏色

在做展示型的網站時,可能會希望切到不同的區域時,可以將選單的背景色修改成對應的樣式,以往習慣監聽 scroll 滾動事件,再根據高度計算區域範圍,再給選單設定對應的 CSS。現在也可以試著用 IntersectionObserver 取代監聽滾動:

<style>
  body, html {
    margin: 0;
    padding: 0;
  }
  header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    transition: background-color 0.3s ease;
  }
  nav {
    display: flex;
    justify-content: center;
    padding: 1rem;
  }
  nav a {
    color: white;
    text-decoration: none;
    margin: 0 1rem;
  }
  section {
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2rem;
    font-weight: bold;
  }
  #section1 { background-color: #FFCCCB; }
  #section2 { background-color: #CCCCFF; }
  #section3 { background-color: #D3EFD3; }
</style>
<header id="mainHeader">
    <nav>
      <a href="#section1">Section 1</a>
      <a href="#section2">Section 2</a>
      <a href="#section3">Section 3</a>
    </nav>
</header>

<section id="section1" data-color="#FF6666">
  <h2>Section 1</h2>
</section>

<section id="section2" data-color="#6666FF">
  <h2>Section 2</h2>
</section>

<section id="section3" data-color="#94A437">
  <h2>Section 3</h2>
</section>
const header = document.getElementById('mainHeader');
const sections = document.querySelectorAll('section');

const observerOptions = {
  threshold: 0.5
};

const observerCallback = (entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      header.style.backgroundColor = entry.target.dataset.color;
    }
  });
};

const observer = new IntersectionObserver(observerCallback, observerOptions);

sections.forEach(section => {
  observer.observe(section);
});

延遲載入 JavaScript

在某些情況下,我們不希望頁面一載入就執行所有 JavaScript,而是希望根據需要延遲載入,此時也能利用 IntersectionObserver 這小技巧來優化頁面,讓使用者滑動到特定元素時才執行與這些元素相關的程式碼。

const scriptsToLoad = document.querySelectorAll('.lazy-script');
const loadScript = (entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const script = document.createElement('script');
      script.src = entry.target.dataset.src;
      script.onload = () => {
        const sectionId = entry.target.closest('section').id;
        const outputId = 'output' + sectionId.slice(-1);
        document.getElementById(outputId).textContent = `${sectionId} 已加載並執行`;
      };
      document.body.appendChild(script);
      observer.unobserve(entry.target);
    }
  });
};
const observer = new IntersectionObserver(loadScript, { threshold: 0.5 });
scriptsToLoad.forEach(script => observer.observe(script));

範例程式碼

https://mukiwu.github.io/web-api-demo/observer2.html

小結

以上,有任何問題,都歡迎留言討論


上一篇
Day23. 深入了解 Intersection Observer API 與其應用 I
下一篇
Day25. 另一種儲存資料的方式:IndexedDB API
系列文
可愛又迷人的 Web API28
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言