-
[JS ํฌํธํด๋ฆฌ์ค ๋ง๋ค๊ธฐ] ์ ํํ ๋ฒํผ์ ํ์ด๋ผ์ดํธ ์ฃผ๊ธฐ (์์๋ณ๊ฒฝ)Mini Projects/make Portfolio 2022. 3. 24. 13:26
2022.03.23
๐คโ์ด๋ป๊ฒ ์ ํ๋ ๋ฒํผ์ ํด๋์ค๋ฅผ ์ถ๊ฐํ ๊น?
ํ์ฌ ์ํ๋ work__categories๋ผ๋ ํฐ ํด๋์ค ์์ 3๊ฐ์ category__btn์ด ๋ค์ด๊ฐ ์๋ค.
<div class="work__categories"> <button class="category__btn selected" data-filter="*">All<span class="category__count selected">5</span></button> <button class="category__btn" data-filter="js">Javascript<span class="category__count">3</span></button> <button class="category__btn" data-filter="react">React<span class="category__count">2</span></button> </div>
category__btn์ ํด๋ฆญํ์ ๋, ํด๋ฆญ ๋ ๋ฒํผ์ด selected๋๋๋ก ๋ง๋ค๊ณ ์ถ๋ค.
(์ฆ, ๋ฒํผ์ ์ ํํ์ ๋, ํด๋น ๋ฒํผ์๋ง!! ํด๋์ค๋ฅผ ๋ฃ์ด์ ์ ํ๋ ํจ๊ณผ๋ฅผ ๋ง๋ค๊ณ ์ถ๋ค.)
์ผ๋จ, ๊ฐ ๋ฒํผ์ ํธ์ถํ๋ ๋ฐฉ๋ฒ์ event.target์ด๋ผ๋ ํจ์๋ก ํธ์ถ์ด ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ ์ด์ ์๊ฐ์ ํตํด ๋ฐฐ์ ๋ค.
๊ทธ๋์ ์ด ๊ธฐ๋ฅ์ ์ด์ฉํด์ ๊ฐ ๋ฒํผ์ ์ด๋ป๊ฒ selected๋ผ๋ ํด๋์ค๋ฅผ ์ถ๊ฐํ๋ฉด ์ข์์ง ๊ณ ๋ฏผํ๋ค.
๐โ์ด๋ ๊ฒ ํ๋ฉด ๋์ง ์์๊น?
1) ํด๋ฆญ๋ ๋ฒํผ์ data-๊ฐ๊ณผ ๋์ผํ ๊ฐ์ด ์๋ ์์์ ํด๋์ค๋ฅผ ์ถ๊ฐํ๋๋ก ํ๋ฉด ๋์ง ์์๊น?
work__categories๋ฅผ ํด๋ฆญํด์ event.target.dataset.filter๋ฅผ ํตํด ๊ฐ ๋ฒํผ์ data-filter๊ฐ์ ๊ฐ์ ธ์์ผ๋ ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ฌํ์ฉํ๋ฉด ์ด๋จ๊น?๋ผ๋ ์๊ฐ์ ํ๋ค.
๊ทธ๋์, data-filter๊ฐ์ ๊ฐ์ ธ์จ ํจ์ ์์ selected๋ผ๋ ํด๋์ค๋ฅผ ์ถ๊ฐํด๋ดค๋ค.
setTimeout(() => { projects.forEach((project) => { if (filter === '*' || filter === project.dataset.filter) { //ํด๋น ํํฐ๊ฐ์ ์ ํํ๋ฉด ์ ํ๋ ํํฐ๊ฐ ์๋ ์นดํ ๊ณ ๋ฆฌ๋ฒํผ์ selected๋ผ๋ ํด๋์ค๋ฅผ ์ถ๊ฐํด๋ณด์ const categoryBtn = document.querySelector('category__btn'); categoryBtn.classList.add('selected'); project.classList.remove('invisible'); .... });
ํ์ง๋ง ์ด๋ ๊ฒ ์ ์ผ๋ ์๋๋ค. ๋๋ฒ๊น ์ ํด๋ณด๋ categoryBtn์ ๊ฐ์ฅ ์ฒ์๋ฒํผ (ํ๋ฒํผ)์ selected๋ผ๋ ํด๋์ค๊ฐ ๋ค์ด๊ฐ๋ค.
๋๋ ์ด๋ ๊ฒ ์๋๋ ๊ฑฐ๋ผ ์๊ฐํ๋ค.
์ฝ๋ ์์๊ฐ ์ค์ ๊ฐ categoryBtn.classList.add('selected');filter๊ฐ์ด js์ธ ๋ฒํผ ํด๋์ค์
selected๊ฐ ์ถ๊ฐ๋จ๊ฐ์ฅ ์ต์๋จ์ ๋ฒํผ ํด๋์ค์
selected๊ฐ ์ถ๊ฐ๋จ[์ฐธ๊ณ ] project.classList.remove('invisible');project.invisible project.invisible ๋ด๊ฐ ์์๊ฐ์ด ์๊ฐํ๋ ์ด์ ๋ ๋ด๊ฐ ์ ํํ ๋ฒํผ์ filter๊ฐ๊ณผ project์ filter๊ฐ์ด ๊ฐ์ผ๋ฉด project์ ํด๋์ค๋ฅผ ์ถ๊ฐํ๋ผ๋ ๋ช ๋ น์ ๊ธฐ์กด์ ๋ดค์๊ธฐ ๋๋ฌธ์ด์๋ค.
๊ทธ๋ ๋ค๋ฉด, ์นดํ ์ฝ๋ฆฌ๋ ๋ง์ฐฌ๊ฐ์ง๋ก filter๊ฐ์ด ์์ผ๋ ๋ด๊ฐ ์ ํํ ๋ฒํผ์ filter๊ฐ๊ณผ project์ filter๊ฐ์ด ๊ฐ์ผ๋ฉด category__btn์ ํด๋์ค๋ฅผ ์ถ๊ฐํ๋ฉด ๋๋๊ฑฐ ์๋๊ฐ?๋ผ๊ณ ์๊ฐ๋ค.
ํ์ง๋ง ์ค์ ๋ก ์๋์์ผ๋ดค์ ๋, ๋ด๊ฐ ์ ํํ ๋ฒํผ์ด ์๋๋ผ ๊ฐ์ฅ ์ต์๋จ์ ์๋ ๋ฒํผ์ selected๋ผ๋ ํด๋์ค๊ฐ ์ถ๊ฐ๋๋ค.
๊ทธ๋ ๋ค๋ ๋ง์, ๋ด๊ฐ ์ ํํ ๋ฒํผ์ด ํ์ผ์ด ๋์ง ์์๋จ ๊ฒ์ด๋ค.
์ง๊ธ ์ด ๊ธ์ ์์ฑํ๋ฉด์ ์ฐฌ์ฐฌํ ๋ฏ์ด๋ณด๋, ๋น์ฐํ ์๋ํ์ง ์์ ์ ๋ฐ์ ์๋ค.
์๋ํ๋ฉด project์ ๊ฒฝ์ฐ์๋ ํด๋น filter๊ฐ๊ณผ '์ง์ ์ '์ผ๋ก ์ผ์นํ๋ ํญ๋ชฉ์๋ง ํด๋์ค๋ฅผ ์ถ๊ฐํ๋๋ก ์ค๊ณ๋์ด์๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋ฐ๋ฐ ๋๋ project์ filter๊ฐ์ด ๋ง์ผ๋ฉด category์๋ ์ถ๊ฐํด์ค๋ผ๋ '๊ฐ์ ์ '์ธ ๋ช ๋ น์ ๋ด๋ ธ๊ธฐ ๋๋ฌธ์ด๋ค.
์ปดํจํฐ๋ ๋ด๊ฐ ์ํ๋ ํ๋์ '์์ฃผ ๊ตฌ์ฒด์ ์ผ๋ก'์ด์ผ๊ธฐ ํด์ค์ผ ํ๊ธฐ ๋๋ฌธ์ ์ด๋ฐ ๋ช ๋ น์ ์ ํ ์ดํดํ์ง ๋ชปํ๋ค.
๋ด๊ฐ ์ํ๋ ๋ฐฉ๋ฒ์ผ๋ก ์นดํ ๊ณ ๋ฆฌ๋ฅผ ์ ํํ๊ณ ์ถ๋ค๋ฉด, project๋ ๋์ผํ ๋ฐฉ๋ฒ์ผ๋ก ์ฝ๋๋ฅผ ๋ง๋ค๋ฉด ๋ ๊ฒ ๊ฐ์ ๋ง๋ค์ด๋ณด์๋ค.
workCategories.addEventListener('click', (event) => { //๋ฒํผ์ ๋๋ฅด๋ฉด ๋ฐํ๋๋ ๊ฐ filter๊ฐ์ ๊ฐ์ ธ์ด const filter = event.target.dataset.filter || event.target.parentNode.dataset.filter; if (filter == null) { return; } //์นดํ ๊ณ ๋ฆฌ ๋ฒํผ์ ๋ชจ๋ ๋ถ๋ฌ์จ๋ค. const categoryBtns = document.querySelectorAll('.category__btn'); //์นดํ ๊ณ ๋ฆฌ ๋ฒํผ์ ๋ชจ๋ ๋๋ฉด์, ๋ด๊ฐ ์ ํํ ๊ฐ๊ณผ ์นดํ ๊ณ ๋ฆฌ ๋ฒํผ์ filter๊ฐ์ด ๊ฐ๋ค๋ฉด 'selected'ํด๋์ค๋ฅผ ์ถ๊ฐํ๊ณ //๊ทธ๋ ์ง ์๋ค๋ฉด ๋ฒํผ์ ์ ๊ฑฐํ๋ค. categoryBtns.forEach((category) => { filter === category.dataset.filter ? category.classList.add('selected') : category.classList.remove('selected') });
์ด๋ ๊ฒ ํ๋ ์๋์ด ๋๋ค.
ํ์ง๋ง ๋ฌธ์ ๊ฐ ์๋ค.
1. ๋ฐ๋ณต๋ฌธ์ ํตํด ๋ฐฐ์ด ๊ฐ์ ์ผ์น์ฌ๋ถ๋ฅผ ํ์ธํ๋ ๊ฒ์ ๋๋ฌด ์๊ฐ์ ์ผ๋ก ์ค๋ ๊ฑธ๋ฆฐ๋ค. ์ฆ, ์๊ฐํจ์จ์ฑ์ด ์ข์ง ์๋ค.
๋จ์ํ ์ ํ๋ ๊ฐ์ ํ์ด๋ผ์ดํธํ๋๋ฐ ๋ฐ๋ณต๋ฌธ์ ๋ฃ์ ์ ๋์ ์ฝ๋๋ฅผ ์ง๋๊ฑด ์ข ์ค๋ฒ์คํ์ด๋ ์๊ฐ์ด ๋ ๋ค.
2. ๊ธฐ์กด์ 'All'์ ์ ํ๋์ด์๋ ํ์ด๋ผ์ดํธ๋ฅผ ์ ๊ฑฐํ๊ณ ๋ชจ๋ ๋ฒํผ์ด ๋นํ์ฑํ ๋์ด์๋ ์ํ๋ก ์์ํ๋๋ฐ, ๋ง์ ๊ตฌํํ๊ณ ๋๋๊น ๊ธฐ๋ณธ๊ฐ์ผ๋ก 'All'์ด ์ ํ๋์ด์๊ณ , ๋ค๋ฅธ ๋ฒํผ์ ๋๋ฅด๋ฉด ํด๋น ๋ฒํผ์ด ํ์ฑ๋๋๋ก ๋ง๋๋๊ฒ ๋ ์ข์ ๊ฒ ๊ฐ๋จ ์๊ฐ์ด ๋ค์๋ค.
์ ๋๊ฐ์ง ๋ฌธ์ ๋ฅผ ํ๋ฒ ํด๊ฒฐํด๋ณด์.
2) ๋ฒํผ์ ๋๋ ์ ๋, ํด๋น ๋ฒํผ์ ๋ ธ๋์ด๋ฆ์ ํ์ฉํ๋ค.
workCategories.addEventListener('click', (event) => { ... //์ ํ๋ ์ํ๋ฅผ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๊ฐ์ ธ์จ๋ค. const selected = document.querySelector('.category__btn.selected'); selected.classList.remove('selected'); });
๋จผ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฒํผ์ด ํ์ฑํ ๋์ด์๋๋ก ๋ง๋ค์ด ๋ณด์.
๊ธฐ๋ณธ All๋ฒํผ์ ๋ชจ๋ ํ์ฑํ ๋๋๋ก ๋ง๋๋ ๋ฐฉ๋ฒ์ ์์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก selected ๋์ ๋ ํด๋์ค๋ฅผ ์ ์ฉ์ํค๋ ๊ฒ์ด๋ค.
selected(์ ํ๋ ์ํ)๋ฅผ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๊ฐ์ ธ์ค๊ณ , ํด๋ฆญ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์นดํ ๊ณ ๋ฆฌ ๋ฒํผ์ selected ํด๋์ค๋ฅผ ์์ค๋ค.
์ด์ ๋ด๊ฐ ์ ํํ ๋ฒํผ์ด ํ์ด๋ผ์ดํธ ๋๋๋ก ๋ง๋ค๊ฑด๋ฐ ์์ 1๋ฒ์์๋ ์ ํํ ๋ฒํผ์ data ๊ฐ์ ๊ฐ์ ธ์์ ํด๋น data์ ์ผ์นํ๋์ง ๋ฐ๋ณต๋ฌธ์ ๋๋ ธ์ง๋ง, ์ด๋ฒ์๋ ๊ทธ๋ฅ event.target์ ์ด์ฉํด ์ ํํ ๋ฒํผ์ ๊ฐ์ ธ์ค๋ฉด ๋๋ค.
์ด๋ ๊ฒ ์ฌ์ด ๋ฐฉ๋ฒ์ด ์์๋๋ฐ ์? ๋ผ๊ณ ๋ฌป๋๋ค๋ฉด, ๋๋ ๋ด๊ฐ ๋ฒํผ์ ๋๋ ์ ๋ ๋ฐํ๋๋ filter๊ฐ์ ์ด์ฉํ๊ณ ์ถ์์ ๋ฟ..์ด๋ผ๊ณ ํด๋์.
event.target์ ์ด์ฉํ๋ฉด ๋ด๊ฐ ์ ํํ ๋ฒํผ์ ์์๊ฐ ์ถ๋ ฅ๋๋ค. ๊ทธ๋ฌ๋ฉด ์ฌ๊ธฐ์ ๋ฐ๋ก class๋ฅผ ์ถ๊ฐํ๋ฉด ๋๋ค.
workCategories.addEventListener('click', (event) => { //์ ํ๋ ์ํ๋ฅผ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๊ฐ์ ธ์จ๋ค. const selected = document.querySelector('.category__btn.selected'); selected.classList.remove('selected'); // ๋ฒํผ์ ๋๋ ์ ๋ ํด๋น ๋ฒํผ์ selected ํด๋์ค๊ฐ ๋ค์ด๊ฐ๋๋ก ํ๋ค. const target = event.target.nodeName === 'BUTTON' ? event.target : event.target.parentNode; console.log(event.target); target.classList.add('selected'); });
๊ทธ๋ฐ๋ฐ ์ nodeName์ด ๋ฒํผ์ธ ํญ๋ชฉ๋ง ์ ํํ๋๋ก ์กฐ๊ฑด๋ฌธ์ ๋ง๋ค์๋ํ๋ฉด, ์ ๊ทธ๋ฆผ์์์ ๊ฐ์ด button ์์ ์์ span์์๊ฐ ๊ฐ์ด ๋ค์ด๊ฐ ์์ด์ span์ ๋๋ฅด๊ฒ ๋๋ฉด ์๋์ด ์๋๋ค. ๊ทธ๋์ ์์๊ฐ button์ด ์๋๋ฉด (== span์ด๋ฉด) ํด๋น ํ๊ฒ์ ๋ถ๋ชจ๋ ธ๋๋ฅผ ์ ํํ๋๋ก ๋ง๋ ๊ฑฐ๋ค.
์ง , ์ด๋ ๊ฒ ํ๋ฉด ์ํ๋ ๋๋ก ์ ์ ํ๋๊ณ ์๋๋๋ค.
์ญ์, ์ฌ๋ฌ๊ฐ์ง ๋ฐฉ๋ฒ๋ก ์ด ์๋ ๊ฒ ๊ฐ๋จ ์๊ฐ์ด ํ๋ฒ๋ ๋ค๋ฉด์ ๋ด๊ฐ ํด๋์ค๋ฅผ ์ถ๊ฐํ๊ณ ์ ๊ฑฐํ๋๋ฐ ๋ญ๊ฐ ์ข ํท๊ฐ๋ฆฌ๊ณ ์์๊ตฌ๋๋ฅผ ์๊ฒ ๋๋ค.
eunne's github: https://github.com/eunne/Project_Portfolio.git
'Mini Projects > make Portfolio' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ