본문으로 건너뛰기

필터, 모드 전환, 무한 스크롤

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개씩 카드를 보여줍니다.

용어 정리

용어
datasetdata-* 속성을 JS에서 다루는 객체
localStorage브라우저에 값을 저장하는 저장소
URLSearchParamsURL 쿼리스트링을 읽고 수정하는 객체
IntersectionObserver요소가 화면에 들어오는지 감지하는 브라우저 API
rootMargin감지 영역을 얼마나 넓힐지 정하는 옵션