바닐라 자바스크립트로 좌표값을 찍어서 효과를 주려고 할 때마다 효과를 주려는 높이를 콘솔로 찍어서 높이를 재는게 너무 불편해서 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
// 구현 계획
// 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 |
---|---|
자바스크립트 object, class문법 (0) | 2024.01.12 |
[국비 프론트 수업] 제이쿼리로 유효성 검사 (0) | 2023.10.27 |
영수증 유효성 검사_Json - 데이터 가져오기, 유효성 검사 (2) | 2023.10.25 |
Js006_Form4 (0) | 2023.10.24 |
댓글 영역