본문 바로가기
Front-End 🧚🏻/Vanilla JS

[Vanilla JS] section 이름 labeling using IntersectionObserver

by 돼지고기맛있다 2022. 3. 30.
반응형

최근 포트폴리오 웹 사이트를 제작하고 있습니다..ㅎㅅㅎ 

 

사실 지금까지는 항상 프론트엔드 프레임워크를 사용해서만 개발해왔습니다. 

 

하지만 정작 웹 개발의 기본인 "HTML, CSS, JS"와 같이 기본적인 부분들을 놓치고 있는건 아닌가 하는 생각이 들었고 그렇게 웹 포트폴리오 사이트를 개발하게 됐습니다. 

 

오늘 포스팅할 내용은 IntersectionObserver를 이용해서 특정 section에 들어갔을 때 해당 Section에 어울리는 이름으로 Label을 동적으로 지정해주는 그런 기능을 만드는 내용입니다!

 

그럼 가장 먼저 IntersectionObserver가 뭔지부터 얘기를 해봐야겠죠?!

 

🦄 IntersectionObserver란?

https://developer.mozilla.org/ko/docs/Web/API/Intersection_Observer_API

 

Intersection Observer API - Web API | MDN

Intersection Observer API는 타겟 요소와 상위 요소 또는 최상위 document 의 viewport 사이의 intersection 내의 변화를 비동기적으로 관찰하는 방법입니다.Intersection Observer API는 타겟 요소와 상위 요소 또는

developer.mozilla.org

위에 MDN 사이트를 읽어보면 나와있습니다 :)

 

간략하게 말씀드리면!

 

우선 Intersection Observer API는 어떠한 요소와 그의 상위요소 혹은 최상위 document의 viewport 사이에 intersecton이 일어나는 경우 이 변화를 비동기적으로 관찰하는 것이 가능하도록 해주는 아주 유용한 API 입니다!

 

왜 유용한지는 사용되는 예시를 보면 알 수 있는데요!

 

  • Lazy Load 구현
  • Infinite-scroll 구현
  • 광고 수익 계산 
  • 결과 표시 여부에 따라 어떠한 작업 및 애니메이션 수행 여부 결정

 

이렇게 다양하게 활용될 수 있기 때문에 정말 좋은 API라고 할 수 있습니다! ㅎㅎㅎ

 

저는 이 "Intersection Observer"를 어떻게 이용할것이냐면!

 

바로 section에 이 Observer를 등록해놓고 해당 section이 화면에 보인 경우에 보이고 싶은 메세지를 가져와서 label을 설정해 줄 것이랍니다!

 

🦄 구현

section labeling 예시

위의 사진을 보면 왼쪽 하단에 귀여운 글씨로 라벨링이 되어있는걸 볼 수 있습니다. 이렇게 귀여운 라벨링을 하러 가봅시다 ㅎㅎㅎ!

 

🦄 HTML 

<body>
	<!-- Label -->
	<div class="label">
		<div class="label__text">Welcome to my page</div>
	</div>

..some code
</body>

 

위와 같이 Label HTML 코드를 작성해줍니다. 

간단하죠? 저는 Body tag 바로 하단에 작성을 해주었어요.

 

🦄 CSS

/* label */
.label {
  position: fixed;
  height: 30px;
  bottom: 0;
  width: 100vh;
  text-align: left;
  left: 0;
  z-index: 10;
  transition: opacity 0.6s;
}

.label__text {
  font-family: "LeeHyunJi";
  position: absolute;
  width: 100%;
  font-size: 25px;
  line-height: 1.3;
  color: var(--color-red);
  overflow: hidden;
  text-align: left;
  padding: calc(7.5vw - 40px) 10px;
  transform: rotate(-90deg);
  transform-origin: left top;
  transition: color 0.3s;
}

위와 같이 CSS 코드도 작성을 해줍니다. 그러면 왼쪽에 원하는 위치에 예쁘게 배치가 될꺼에요! padding은 원하는 값으로 적절히 넣어주시면 됩니다 :)

 

 

🦄 JS

자, 이제 제일 중요한 JS!

 

일단 각 section마다 무슨 label을 달아줄건지 저는 html의 dataset 속성을 이용해서 설정해볼꺼에요!

<!-- Title -->
<section id="title" class="section" data-section="welcome to my page">
...some code
</section>
<!-- Home -->
<section id="home" class="section" data-section="Home">
...some code
</section>

.
.
.

위에 코드처럼 각 영역이 있을건데! 각 영역마다 data-속성을 통해서 section 이라는 정보를 저장해두는거죠 ㅎㅎ그러면 JS 에서 정보를 가져올 수 있습니다!

 

 

다음으로는 section 별로 InersectionObserver를 달아줄겁니다! 바로 이렇게요!

const observerOptions = {
  root: null,
  rootMargin: "0px",
  threshold: 0.3,
};
const observerCallback = (entries, observer) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
     	const label = entry.target.dataset.section;
      	setLabel(label);
    }
  });
};
const labelObserver = new IntersectionObserver(
  observerCallback,
  observerOptions
);

 

IntersectionObserver을 생성해줄 때에는 callback과 option 두 가지를 인자로 넘겨주게 됩니다!

callback은 intersecting observe 과정에서 option에 만족을 하면 실행됩니다!

 

위의 코드에서 기본적인 option 으로는 root, rootMargin, threshold 세 가지가 있습니다. 

 

root: 대상 객체의 가시성을 확인할 때 사용되는 뷰포트 요소인데, 기본값은 브라우저 뷰포트이며 null인 경우는 기본값으로 설정됩니다. 

 

rootMargin: root가 가진 여백입니다. 해당 값은 root요소의 각 측면의 bounding box를 수축시키거나 증가시키며, 교차성을 계산하기전에 적용되고, 기본값은 0px 입니다. 

 

threshold: observer의 콜백이 실행될 때 대상 요소의 가시성 퍼센테지를 나타내는 단일 숫자 혹은 숫자 배열입니다. 예를 들어 뷰포트에 50%이상 보여질 때 callback을 실행시키고 싶다면 0.5로 설정해주면 됩니다. 

 

위의 정의로 볼때 저는 root는 기본 뷰포트로 하고 root에 적용되는 margin은 없애고! 화면에 30% 보여질 때 콜백이 실행될 수 있도록 설정해주었습니다. 

 

callback은 만약 내가 지정한 section이 내가 설정한 threshold이상 화면에 보이고 있다면 true를 반환합니다. 

그렇게 내가 지정한 threshold를 넘었다면 label을 dataset에서 가져와 설정해주면 끝! >_< 정말 쉽죠?

 

 

 

반응형

댓글