Intersection Observer API

yknam·2023년 11월 13일
0
post-thumbnail

h2~h6 detect

detect하는 구문

document.querySelectorAll("h2, h3, h4, h5, h6").forEach((entries) => {
     observer.observe(entries);
});

entries 하나의 예

<h3 id="filebeat--elastic-search-조회">
  <a class="anchor" href="#filebeat--elastic-search-조회">
    <span class="icon icon-link"></span>
  </a>
  Filebeat → Elastic Search 조회
</h3>

IntersectionObserver처리

 const observer = new IntersectionObserver(setCurrent, observerOptions);
  1. 스크롤시 화면 안으로 내용이 들어오면 callback을 보내줌
  2. entries내용중 href부분을 URLencode한다
    filebeat--elastic-search-조회 -> filebeat--elastic-search-%EC%A1%B0%ED%9A%8C
    3.
    내의 anchor class="active"를 remove하고
  3. href="#filebeat--elastic-search-%EC%A1%B0%ED%9A%8C"인것에 "active"를 추가한다.

react code

"use client";

import React, { useEffect } from "react";
import $ from "jquery";

export default function Toc() {
  useEffect(() => {
    $("#dvToc").append($("#contents + ul")).prepend($("#contents"));

    const setCurrent: IntersectionObserverCallback = (entries) => {
      for (let entry of entries) {
        const { id } = entry.target;//->href 내용
        const enid = encodeURI(id);//->utf-8 한글처리
        const tocHeadingEl = document.querySelector(
          `#dvToc a[href="#${enid}"]`
        );
        
        if (!tocHeadingEl) return;
        if (entry.isIntersecting) {
          document
            .querySelectorAll("#dvToc a")
            .forEach((e) => e.classList.remove("active"));
          tocHeadingEl.classList.add("active");
        }
      }
    };
    const observerOptions = {
      threshold: 0.5, //-> 0~1 범위, 1:링크가 root안으로 100%들어와야함
      rootMargin: "0px 0px -96%",
    };
    const observer = new IntersectionObserver(setCurrent, observerOptions);

    document.querySelectorAll("h2, h3, h4, h5, h6").forEach((entries) => {
      observer.observe(entries);
    });
  }, []);
  return <div id="dvToc" className="mt-3 sticky top-8 "></div>;
}

active css

.active {
  @apply font-bold bg-blue-300 dark:bg-indigo-500 dark:text-gray-700;
}

참조링크

profile
50대 개발자 노드, 자바스크립트

0개의 댓글