바닐라 자바스크립트로 좌표값을 찍어서 효과를 주려고 할 때마다 효과를 주려는 높이를 콘솔로 찍어서 높이를 재는게 너무 불편해서 Intersection Observer API를 활용하여 편하게 구현하였다.
아래 코드를 보면 효과를 주고싶은 높이와 윈도우의 자표를 찍어 번거롭게 구현을 하였는데 Intersection Observer API를 쓰면 더 쉽게 효과를 줄 수 있다.
const header = document.querySelector('.header');
const headerHeight = header.getBoundingClientRect().height; // getBoundingClientRect 높이를 반환해주는 함수임
document.addEventListener('scroll', () => { // 화살표 함수
if(window.scrollY > headerHeight) {
header.classList.add('header--dark');
} else {
header.classList.remove('header--dark');
}
});
<div id="container">
<div class="content">One</div>
<div class="content">Two</div>
<div class="content">Three</div>
<div class="content">Four</div>
<div class="content">five</div>
<div class="content">sixe</div>
</div>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
#container {
display: flex;
flex-direction: column;
}
.content {
background-color:black;
width: 100px;
height: 100px;
margin: 10px;
opacity: -1;
transition: opacity 0.5s;
}
.content--change {
background: red;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
opacity: 3;
}
https://baeharam.netlify.app/posts/javascript/intersection-observer
[JS] Intersection Observer 사용법 - 배하람의 블로그
스크롤에 따른 효과를 어떻게 줄 수 있을까? 웹 개발을 하다보면 사용자가 스크롤 하는 상태에 따라서 현재 보여지는 뷰포트에 가시적으로 어떤 엘리먼트가 나타나는지 확인하고 싶을 때가 있
baeharam.netlify.app
// 구현 계획
// 1. 모든 섹션 요소들과 메뉴 아이템들을 가지고 온다.
// 2. IntersectionObserver를 사용해서 모든 섹션들을 관찰해야 한다.
// 3. 보여지는 섹션에 해당하는 내용 아이템을 활성화 시킨다.
// 보여지는 섹션: 다수의 섹션이 동시에 보여진다면, 가장 첫번째 섹션을 선택
// #기본 동작 구현
const sectionIds = ['#home','#about','#skills','#work','#contact',];
const sections = sectionIds.map((id) => document.querySelector(id));
const navItems = sectionIds.map((id) => document.querySelector(`[href="${id}"]`));
// (id)화살표 함수는 가로 안에 넣어야함 아니면 타입 에러가 뜸
const visibleSelections = sectionIds.map(() => false);
let activeNavItem = navItems[0];
const options = {
threshold: [0, 0.25, 0.5],
rootMargin: '-200px 0px 0px 0px',
threshold: [0, 0.98],
};
const observer = new IntersectionObserver(observerCallback, options);
sections.forEach((section) => observer.observe(section));
function observerCallback(entries) {
let selectLastOne; // flag 변수
entries.forEach((entry) => {
const index = sectionIds.indexOf(`#${entry.target.id}`);
visibleSelections[index] = entry.isIntersecting;
selectLastOne =
index === sectionIds.length - 1 &&
entry.isIntersecting &&
entry.intersectionRatio >= 0.95;
});
const navIndex = selectLastOne
? sectionIds.length - 1
: findFirstIntersecting(visibleSelections);
selectNavItem(navIndex);
}
function findFirstIntersecting(intersections) {
const index = intersections.indexOf(true);
return index >= 0 ? index : 0;
}
function selectNavItem(index) {
const navItem = navItems[index];
if (!navItem) return;
activeNavItem.classList.remove('active');
activeNavItem = navItem;
activeNavItem.classList.add('active');
}
[국비 프론트 수업 자바스크립트] 알아야 할 문법 정리 (0) | 2024.01.20 |
---|---|
[국비 프론트 수업] 제이쿼리로 유효성 검사 (0) | 2023.10.27 |
영수증 유효성 검사_Json - 데이터 가져오기, 유효성 검사 (2) | 2023.10.25 |
Js006_Form4 (0) | 2023.10.24 |
[국비 프론트 단위 평가] 이벤트 리스너를 활용해 글자 제어하기 (코드 있음) (0) | 2023.10.24 |
댓글 영역