최근 포트폴리오 웹 사이트를 제작하고 있습니다..ㅎㅅㅎ
사실 지금까지는 항상 프론트엔드 프레임워크를 사용해서만 개발해왔습니다.
하지만 정작 웹 개발의 기본인 "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을 설정해 줄 것이랍니다!
🦄 구현
위의 사진을 보면 왼쪽 하단에 귀여운 글씨로 라벨링이 되어있는걸 볼 수 있습니다. 이렇게 귀여운 라벨링을 하러 가봅시다 ㅎㅎㅎ!
🦄 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에서 가져와 설정해주면 끝! >_< 정말 쉽죠?
댓글