BOOKREST Notice 페이지 (서비스 소개, 규정, 오시는 길, 문의하기 페이지가 모여있는 곳)을 만들던 도중
라는 생각이 들었다.
html에서 a링크를 달면 새로고침으로 다른 페이지를 이동하는 것은 매일 하던 거였으니 새로운 걸 해보고 싶었다. 🤔🤔
animation으로 페이지 이동하는 걸 하려면 html에서는 animation을 줄 페이지들을 한 템플릿 안에서 만들어야 한다.
<div class="noticeTool__category">
<div class="noticeTool__category__title">BOOKREST 이용안내</div>
<div class="noticeTool__category__link">
<a class="js-introduceA js-noticeTool__category__link">BOOKREST란</a>
<a class="js-ruleA js-noticeTool__category__link">규정</a>
<a class="js-faqA js-noticeTool__category__link">자주 묻는 질문</a>
<a class="js-bookrestMapA js-noticeTool__category__link">오시는 길</a>
</div>
</div>
먼저, a링크를 달아서 내용 폼에 관련한 각각의 제목을 적어준다.
자세한 개발 사항은 a링크 BOOKREST란? , 규정 두 가지로 얘기하도록 하겠다.
class 명은 BEM방식으로 지으려고 노력했다.
👉🏻 CSS BEM 참고
a class="js-introduceA" 를 누르면 나오는 폼
<div class="noticeTool__summaryTool">
<!-- js-introduce 여기가 포인트 -->
<div class="noticeTool__summaryTool__box js-introduce noticeShowing">
<div class="noticeTool__summaryTool__box__title">
<h1>BOOKREST란?</h1>
</div>
<div class="noticeTool__summaryTool__box__summary">
BOOKREST는 전공 서적을 대여해주는 서비스입니다. 학기마다 전공 책을
새로 구매하시나요? 구매하셨다면 가격이 부담스럽지 않으셨나요?
머라머라머라
</div>
</div>
</div>
a class="js-ruleA" 를 누르면 나오는 폼
<div class="noticeTool__summaryTool">
<!-- js-rule 여기가 포인트 -->
<div class="noticeTool__summaryTool__box js-rule">
<div class="noticeTool__summaryTool__box__title">
<h1>Rule</h1>
</div>
<div class="noticeTool__summaryTool__box__summary">
<b>Book</b>
책의 종류와 재고는 BOOKREST 사이트에서 확인해주시면 됩니다. 직접
오셔서 대여하려 하시면 이미 예약된 책들도 있어 어려우실 수 있습니다.
BOOKREST 사이트에서 미리 예약하시면 더 빠르고 쉽게 대여하실 수
있습니다.
머라머라머라
</div>
</div>
</div>
위의 두 폼 모두 한 템플릿에서 쓰인 코드다.
class명, css는 모두 똑같이 먹이고 BEM방식으로 js-introduce, js-rule이라 써주면 모든 준비 완료!
이제 Javascript에서 각각의 a링크를 클릭하면 그에 맞는 폼이 나오도록 만들면 된다.
// 각각 내용이 있는 폼
const introduce = document.querySelector(".js-introduce");
const rule = document.querySelector(".js-rule");
// a링크
const introduceA = document.querySelector(".js-introduceA");
const ruleA = document.querySelector(".js-ruleA");
// css 애니메이션
const NOTICESHOWING_CN = "noticeShowing";
각각의 변수를 선언해준다. noticeShowing에 관한 코드는 아래 있다.
.noticeShowing {
opacity: 1;
z-index: 10;
transform: scale(1);
}
noticeShowing은 introduce폼과 rule폼을 보였다 사라졌다 하는 animation을 주는 역할을 한다.
근데 모든 폼이 opacity가 0이면 아무것도 안 보이니 introduce폼이 기본으로 설정해두었다.
따라서 위에 html을 보면 introduce폼 class에 noticeShowing이 적어져 있다.
const elementList = [introduce, rule];
const elementLinkList = [introduceA, ruleA];
let currentIndex = 0;
let beforeIndex = 0;
elementList 변수는 introduce와 rule 객체(DOM)가 있는 배열이다.
elementLinkList는 각각의 DOM으로 갈 수 있는 링크 태그로 이루어진 배열이다.
currentIndex는 현재 보이는 배열의 인덱스, beforeIndex는 전에 보였던 배열의 인덱스다.
const noticeInit = () => {
elementLinkList.map((link, index) => {
link.addEventListener("click", () => {
addClassNameToCurrentElement(index);
});
});
};
noticeInit();
noticeInit 함수는 제일 먼저 실행되며 elementLinkList 각 요소의 EventListener를 부착한다.
이때 map 메소드의 인덱스 값을 addClassNameToCurrentElement의 인자로 사용한다.
const addClassNameToCurrentElement = (index) => {
elementList[beforeIndex].classList.remove(NOTICESHOWING_CN);
elementList[index].classList.add(NOTICESHOWING_CN);
beforeIndex = index;
};
link 요소가 click되면 addClassNameToCurrentElement 함수에 index 값을 인자로 실행한다.
elementList 배열의 beforeIndex번째 객체의 classList에 NOTICESHOWING_CN을 지워주고, elementList 배열의 index번째 객체의 classList에 NOTICESHOWING_CN을 더해준다.
beforeIndex = index;
beforeIndex에 인덱스 값을 할당해 주었다.
click 되면 beforeIndex번째의 NOTICESHOWING_CN를 지우면 전에 있는 건 안보이고 현재 누른 것만 보이게 되기 때문에 다음에 눌렀을 때를 위해서 beforeIndex 변수에 지금 누른 값인 index를 할당하였다.
url을 보면 같은 한 페이지임을 알 수 있다.
새로고침이 아닌 오른쪽 틀이 animation으로 나오게 된다. 👏🏻👏🏻👏🏻
const noticeAnimateIntroduce = () => {
introduce.classList.add(NOTICESHOWING_CN);
rule.classList.remove(NOTICESHOWING_CN);
bookrestMap.classList.remove(NOTICESHOWING_CN);
inquiry.classList.remove(NOTICESHOWING_CN);
};
const noticeAnimateRule = () => {
rule.classList.add(NOTICESHOWING_CN);
introduce.classList.remove(NOTICESHOWING_CN);
bookrestMap.classList.remove(NOTICESHOWING_CN);
inquiry.classList.remove(NOTICESHOWING_CN);
};
const noticeInit = () => {
introduceA.addEventListener("click", noticeAnimateIntroduce);
ruleA.addEventListener("click", noticeAnimateRule);
bookrestMapA.addEventListener("click", noticeAnimateBookrestMap);
inquiryA.addEventListener("click", noticeAnimateInquiry);
};
noticeInit();
refactoring 전에는 배열이랑 인덱스를 사용하지 않고 각 요소마다 함수를 만들었다.
하면서도 비효율적이라고 느껴졌다..
만약 더 많은 페이지가 추가된다고 하면 함수를 몇십 개 더 만들어야 하는 거다.
그래서 배열과 인덱스를 활용하였다.
refactoring 후 elementList와 elementLinkList의 배열에 넣어주기만 하면 된다.
const elementList = [introduce, rule];
const elementLinkList = [introduceA, ruleA];
어떻게 하면 더 효율적인 코드가 될 수 있는지 생각하고 배우며 더 많은 기능의 javascript를 공부해야겠다.
👊🏻👊🏻👊🏻
항상 생각하고 실천하는 자세가 보기좋네요 !!! 많이 배우고 갑니당 🔥🔥🔥🔥