상세 컨텐츠

본문 제목

IntersectionAPI 오디 한번 싸용해 보올깡

자바스크립트

by e7e 2024. 4. 16. 14:09

본문

무한 스크롤이나 그 비스무리한 곳에 사용하면 좋을 

IntersectionObserver라는 것이 있엉, 요기서 소개한당

 

부모태그 안의 자식이 부모보다 커질때, 보통  css overflow 속성을 이용

사용자가 스크롤바를 이용할 수 있게 해주는뎅,

IntersectionObserver는 특정 자식(target)이 부모 안에서 부모 스크롤바를

움직일 때 몇 퍼센트가 지금 눈에 보이는가?를 관찰해 주고

등록한 포인트들(threshhold)을 지날 때 등록한 callback함수를 불러준당

 

더 자세한 내용은 역시 자바스크립트의 성지인 MDN에서 확인(아래 링크)

https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver

하장. (문서를 읽는 능력은 필수당.~~ 자꾸 읽어보도록 하장!!!)

 

복사/붙여넣기가 예상되는 핵심 코드는 아래와 같당(일단 의미 파악에 힘쓰장!)

      let options = {
        // 감시대상 부모
        root: document.querySelector("#scrollArea"),
        rootMargin: "0px",
        // 모니터링 할 포인트(퍼센트), 부모 안에서 얼만큼 보이는가?
        threshold: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
      };

      // 감시 대상, 보통 스크롤 영역안에 존재
      const target = document.querySelector("#e7e");

      // 모니터링 포인트에 실행할 함수 핸들러
      const callback = (entries, observer) => {
        entries.forEach((entry) => {
          console.log("체크 겹침", entry.isIntersecting);
          console.log("체크 비율", entry.intersectionRatio);
        });
      };

      // IntersectionObserver(겹침체크 관찰자 생성)
      let observer = new IntersectionObserver(callback, options);
      // 관찰 대상 등록
      observer.observe(target);

 

위 핵심코드 이해를 위한 샘플 html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <style>
      * {
        text-align: center;
      }
      #scrollArea {
        /* width:500px; */
        height: 650px;
        border: 1px solid black;
        overflow: scroll;
        box-sizing: border-box;
      }
      #e7e {
        height: 450px;
        background-color: rgb(40 40 90 / 100%);
        transition: background-color 0.8s;
        color: white;
        font-size: 5em;
        border: 5px groove;
        /*  line-height: 450px;*/
        text-shadow: 0 0 4px #ccc, 0 -5px 4px #ff3, 2px -10px 6px #fd3,
          -2px -15px 11px #f80, 2px -19px 18px #f20;
      }
      #ratioDisp {
        font-size: 0.3em;
        color: yellow;
        background-color: black;
        position: relative;
        top: -520px;
        text-shadow: none;
      }
    </style>
  </head>
  <body>
    <h1>IntersectionAPI 사용해 보아용</h1>
    <hr />
    <div id="scrollArea">
      <script>
        const ranColor = () => {
          let rgbColor = `rgb(
                              ${Math.round(Math.random() * 255)} ,
                              ${Math.round(Math.random() * 255)} ,
                              ${Math.round(Math.random() * 255)} 
                            )`;

          return rgbColor;
        };

        const surplus = "고개위 고개 숙인 고 개";
        let colorStyle = "color:fcolor;background-color:bcolor";
        const len = 10;
        let i = 1;
        for (; i <= len; ) {
          document.write(`<h1 style='${colorStyle
            .replace("fcolor", ranColor())
            .replace("bcolor", ranColor())}' >
                              ${surplus}${i}
                         </h1>`);
          i++;
        }
      </script>
      <div id="e7e" style="border: 1px solid blue">
        <div>안농</div>
        <div>난 ET</div>
        <div>E7E 라고 해</div>
        <div>넌 누구얌</div>
        <span id="ratioDisp">10%</span>
      </div>
      <script>
        let cnt = i - 1;
        i = 1;
        for (; i <= len; ) {
          document.write(`<h1 style='${colorStyle
            .replace("fcolor", ranColor())
            .replace("bcolor", ranColor())}' >
                              ${surplus}${cnt + i}
                         </h1>`);
          i++;
        }
      </script>
    </div>
    <script>
      const e7e = document.querySelector("#e7e");
      const ratioDisp = document.querySelector("#ratioDisp");
      const oneMore = ratioDisp.cloneNode(true);
      oneMore.style.top = "-35px";
      e7e.appendChild(oneMore);

      let options = {
        root: document.querySelector("#scrollArea"),
        rootMargin: "0px",
        //  threshold:1.0        // target is 100% visible
        // 인터섹트 퍼센트 지정, 10% 단위로
        threshold: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
      };

      const target = document.querySelector("#e7e");
      const callback = (entries, observer) => {
        // alert("온제 실행 되징?");
        // console.log(observer.takeRecords());
        // 요걸(observer.takeRecords()) 부르면
        // pending intersection list 클리엉
        entries.forEach((entry) => {
          console.log("체크 겹침", entry.isIntersecting);
          console.log("체크 비율", entry.intersectionRatio);
          e7e.style.color = ranColor();
          e7e.style.backgroundColor = ranColor();
          ratioDisp.innerHTML = `겹침: ${Math.ceil(
            entry.intersectionRatio * 100
          )}%`;
          oneMore.innerHTML = `겹침: ${Math.ceil(
            entry.intersectionRatio * 100
          )}%`;
        });
      };

      // IntersectionObserver(겹침체크 관찰자 생성)
      let observer = new IntersectionObserver(callback, options);
      // 관찰 대상 등록
      observer.observe(target);
      //   console.log(observer.takeRecords());
      //   처음에 무조건 target 일단 체킁, alert확인
    </script>
  </body>
</html>

 

위 소스를 실행하면 아래와 같은 결과를 얻는당.

스크롤바를 위 아래로 살살 움직이면서 겹침: ?? %가 나오는 부분에 딥중

target으로 등록한 #e7e div가 #scrollArea 안에서 자신을 몇% 드러냈는지

나타낸당. 요거이 이해되면  복사/붙여넣기 식으로 사용해도

아무도 머라하지 않는당.  이해되면 어디에 사용할지들 고민해 보장! 

 

IntersectionObserver를 사용하는 핵심코드 이외의 부분에  일부러

유지보수 어렵게  아주 안 좋은 문자열 더하기 방식으로 "고개위 고개 ......" 를

권장되지 않는 document.write를 이용해서 출력했당.

시간이 허락된다면 객체지향방식으로 리팩토링 해보길 강력히 추천한당.

나쁜 습관을 좋은 습관으로 바꿀 수만 있다면,

두려움을 용기로 바꾼 것만과 맞먹을 내공을 얻게 될 거이당.~~ (^-^)

당신은 두려움을 모르는 도전자당!!!!!

 


 

다수가 소수를 지배하듯

소수도 다수를 지배한당

 

대세라서 널리 퍼지고

희소해서 꽈악 집중 된당

 

나는 나를 널리 지배하고

나에게  꽈악 지배당한당.

 

난 희소하고 또 대세당

난 나당. I Am!

 

Null Pointer Exception에도 미동없는 나!

이런 나 Null 사랑하지 않는 건가요?

 

https://www.youtube.com/watch?v=6ZUIwj3FgUY

 

관련글 더보기