필터, 모드 전환, 무한 스크롤
js/main.js는 화면에 렌더링된 DOM에 동작을 붙이는 파일입니다.
핵심 객체는 세 개입니다.
ModeToggle
Filter
InfiniteScroll
모드 전환
사이트는 두 가지 모드를 가집니다.
| 모드 | 의미 |
|---|---|
dev | 개발 작업 중심 |
design | 디자인 작업 중심 |
현재 모드는 body의 dataset에 저장됩니다.
<body data-mode="dev">
JS에서는 이렇게 바꿉니다.
this.body.dataset.mode = mode;
CSS에서는 이렇게 읽습니다.
body[data-mode="dev"] {
--brand-primary: #2563eb;
}
body[data-mode="design"] {
--brand-primary: #ec4899;
}
모드 초기값
getInitialMode() {
const params = new URLSearchParams(window.location.search);
const urlMode = params.get('mode');
if (urlMode === 'design' || urlMode === 'dev') {
return urlMode;
}
const savedMode = localStorage.getItem('zeno-mode');
if (savedMode === 'design' || savedMode === 'dev') {
return savedMode;
}
return 'dev';
}
우선순위는 다음과 같습니다.
URL ?mode=
-> localStorage
-> 기본값 dev
카테고리와 모드 매핑
const CATEGORY_MODE = {
site: 'dev',
toy: 'dev',
UXUI: 'design',
Motion: 'design',
Graphic: 'design',
PDP: 'design'
};
카테고리마다 어느 모드에 속하는지 정합니다.
필터 조건
카드가 보이려면 세 조건을 통과해야 합니다.
현재 모드와 카드 모드가 맞는가?
현재 카테고리와 카드 카테고리가 맞는가?
선택한 기술 태그와 카드 기술 태그가 맞는가?
코드에서는 이렇게 계산합니다.
const shouldShow = modeMatch && catMatch && techMatch;
조건을 통과하면 hidden 클래스를 제거합니다.
card.classList.remove('hidden');
조건에 맞지 않으면 숨깁니다.
card.classList.add('hidden');
기술 태그 칩
기술 태그는 현재 보이는 카드 기준으로 자동 생성됩니다.
const techs = (card.dataset.tech || '')
.split(',')
.map(t => t.trim())
.filter(Boolean);
split(',')은 쉼표 기준으로 문자열을 나눕니다.
"React,JavaScript,CSS"
-> ["React", "JavaScript", "CSS"]
무한 스크롤
무한 스크롤은 Intersection Observer를 사용합니다.
this.observer = new IntersectionObserver(
entries => {
entries.forEach(entry => {
if (entry.isIntersecting && this.visibleCards.length > 0) {
this.loadMore();
}
});
},
{ rootMargin: '200px' }
);
sentinel 요소가 화면 근처에 들어오면 loadMore()가 실행됩니다.
처음 6개 카드 표시
-> 아래 sentinel 근처 도달
-> 다음 6개 표시
-> 더 없으면 End of works
pageSize
pageSize: 6
한 번에 6개씩 카드를 보여줍니다.
용어 정리
| 용어 | 뜻 |
|---|---|
| dataset | data-* 속성을 JS에서 다루는 객체 |
| localStorage | 브라우저에 값을 저장하는 저장소 |
| URLSearchParams | URL 쿼리스트링을 읽고 수정하는 객체 |
| IntersectionObserver | 요소가 화면에 들어오는지 감지하는 브라우저 API |
| rootMargin | 감지 영역을 얼마나 넓힐지 정하는 옵션 |