// HEADER-MODAL
const hBtn1 = document.querySelector('.header-btn.skincare');
const hBtn2 = document.querySelector('.header-btn.body');
const hBtn3 = document.querySelector('.header-btn.hair');
const hBtn4 = document.querySelector('.header-btn.perfume');
const hBtn5 = document.querySelector('.header-btn.home');
const hBtn6 = document.querySelector('.header-btn.kit');
const hBtn7 = document.querySelector('.header-btn.gift');
const hBtn8 = document.querySelector('.header-btn.read');
const modalOpenHeader = document.querySelector('header');
const hModalCloseBtn = document.querySelector('.header-btn.header-close');
const hModal = document.querySelector('.header-modal');
const hModalMenu = document.querySelector('.header-modal-menu');
const hModalSkin = document.querySelector('#modal-skincare');
const hModalBody = document.querySelector('#modal-body');
const hModalHair = document.querySelector('#modal-hair');
const hModalPerfume = document.querySelector('#modal-perfume');
const hModalHome = document.querySelector('#modal-home');
const hModalKit = document.querySelector('#modal-kit');
const hModalGift = document.querySelector('#modal-gift');
const hModalRead = document.querySelector('#modal-read');
//클릭한 메뉴를 제외하고 다른 메뉴 다 닫기
const removeOpens = function (except) {
document.querySelector('.shipping-banner').style.display = 'none';
document.querySelector('body').style.overflow = 'hidden';
hModal.classList.add('on');
gsap.fromTo(
'.header-modal.on',
0.5,
{ height: 0, scaleY: 0.2 },
{ scaleY: 1 }
);
const opens = document.querySelectorAll('.open');
opens.forEach((open) => open.classList.remove('open'));
except.classList.add('open');
hModalCloseBtn.classList.add('open');
modalOpenHeader.classList.add('white-version');
};
hBtn1.addEventListener('click', function () {
removeOpens(hModalSkin);
});
hBtn2.addEventListener('click', function () {
removeOpens(hModalBody);
});
hBtn3.addEventListener('click', function () {
removeOpens(hModalHair);
});
hBtn4.addEventListener('click', function () {
removeOpens(hModalPerfume);
});
hBtn5.addEventListener('click', function () {
removeOpens(hModalHome);
});
hBtn6.addEventListener('click', function () {
removeOpens(hModalKit);
});
hBtn7.addEventListener('click', function () {
removeOpens(hModalGift);
});
hBtn8.addEventListener('click', function () {
removeOpens(hModalRead);
});
클론코딩을 처음 하는 과제에서 네비바에서 해당 메뉴를 클릭하면 그 창만 보이게 하는 기능을 구현하기 위해 버튼 하나하나에 이벤트리스너를 설정하고 클릭한 메뉴를 제외하고 다른 모든 요소에서 open클래스를 제거해 닫아주는 함수를 실행하게 했다. 당연히 간략하게 forEach로 짤 수 없을까? 생각은 했지만 쉽지않아서 일단 구현을 목표로 작성했고,, 코드리뷰를 받고 리팩토링을 해보았다.
const hBtnAll = document.querySelectorAll('.header-btn');
const hModalCloseBtn = document.querySelector('.header-btn.header-close');
const modalOpenHeader = document.querySelector('header');
const hModal = document.querySelector('.header-modal');
const hModalMenuAll = document.querySelectorAll('.header-modal-menu');
// All로 한번에 제어해보기
hBtnAll.forEach((btn, i) => {
btn.addEventListener('click', function () {
removeOpens(hModalMenuAll[i]);
});
});
버튼과 메뉴를 하나하나 다 선택하는 것부터 이벤트리스너를 적용해주는 코드까지 전부 필요없어졌다. querySelectorAll로 모든 버튼과 메뉴를 한번에 선택하고 그렇게 만들어진 버튼이 아이템으로 담긴? 노드 리스트를 forEach로 돌면서 해당 버튼에 맞는 메뉴를 인덱스 번호로 불러와 함수를 실행시키도록 했다.
forEach를 생각했지만 항상 하나의(필수의) 매개변수만을 이용하다보니 두번째 인수로 인덱싱을 할 수 있다는 생각을 못했던 것 같다. 앞으로 메소드를 공부할 때 어떤 것을 매개변수로 들어갈 수 있는지 필수 매개변수말고도 다 들여다보는 습관을 가져야겠다.