본문 바로가기
핀테크 서비스 프론트엔드 개발자 취업 완성 2기/JS

[JS] JavaScript에서 querySelectorAll Elements에 클릭 이벤트 적용하기. with. classList.add() & classList.remove()

by flyda 2022. 4. 22.

1. 내가 원하는 시나리오!!

화면에 2021년도의 내용이 표시가 된다. 

만약 내가 2020을 클릭하면 밑의 사진처럼 2020년의 내용이 표시되게 만들고 싶다! 

내용은 html파일에 직접 넣는 것이 아니라 javascript를 통해서 넣고 싶다. 그 기능을 만들기 위해서 클릭된 연도에 active라는 클래스를 추가하도록 만들 예정이다. 

 

2. 과정_1

<ul class="timeline">
  <li class="year" data-year='2021'></li>
  <li class="year" data-year='2020'></li>
  <li class="year" data-year='2019'></li>
  <li class="year" data-year='2018'></li>
  <li class="year" data-year='2017'></li>
  <li class="year" data-year='2016'></li>
  <li class="year" data-year='2015'></li>
  <li class="year" data-year='2014'></li>
  <li class="year" data-year='2013'></li>
</ul>

나는 year 클래스를 가진 li 중 하나를 클릭하면 data-year에 있는 년도가 출력되는 코드를 만들고 싶다. 

그래서 처음에는 querySelectorAll을 통해서 모두를 선택한 뒤 addeventListener을 넣었다. 

const yearActiveEls = document.querySelectorAll('.year')

yearActiveEls.addEventListener('click', function () {
  console.log(yearActiveEls.dataset.year)
})

하지만 `timeline.js:4 Uncaught TypeError: yearActiveEl.addEventListener is not a function`이라는 에러가 났다.... 

 

그래서 이렇게 그냥 querySelector로 선택하니 당연하게 제일 위에 있는 2021만 선택할 수 있었다. ㅎ 

const yearActiveEl = document.querySelector('.year')

yearActiveEl.addEventListener('click', function () {
  console.log(yearActiveEl.dataset.year)
})

//2021

 

그래서 forEach를 사용하는 방법for문을 사용하는 방법을 찾았는데, 어제 for 문을 배워서 그냥 for 문으로 선택했다. 절대.. 갑자기 forEach문법을 잘 모르겠어서 그런게 아니다...!!!(사실은 처음에 `[]. forEach`를 보자마자 백스텝을 밟았다.

그리고 for( const el for els) 라는 새로운 문법도 신기했다. 자세한 사용법은 공식 문서를 참고하길 바란다. 

 

고친 코드는 다음과 같다!! 

1-1. 중간 성공 코드

다음 코드는 2021을 클릭하면 클릭한 년도를 콘솔창에 출력해주는 코드이다. 

const yearActiveEls = document.querySelectorAll('.year')

for (const yearActiveEl of yearActiveEls) { // 반복 가능한 객체에 대해서 반족하는 문법!! 
  yearActiveEl.addEventListener('click', function () {
    //isActiveYear = !isActiveYear
    console.log(yearActiveEl.dataset.year)
  })
}

이제 li요소를 클릭하면 해당 data-year에 들어있는 값이 나온다!! ㅎㅎㅎ 성공!!!  혹시 data-year이 무엇인지 모른다면 공식문서를 참조하길 바란다. 

 

2. 과정_2

이제 바로 바로 클래스 추가만 해주면 성공!!!인 줄 알았지만, click이벤트를 실행한 뒤 active 클래스를 추가한 뒤 다른 년도를 클릭해도 active가 사라지지 않았다.  무조건 클릭을 통해서 클래스를 없애 주어야 했다. 아니면 클릭했던 모든 li 태그에 active 클래스가 추가되는 문제가 있었다.  

당연히... 2021을 클릭하면 이전에 클릭한 2020에 active가 사라질 줄 알았는데.. ㅠㅠㅠ 너무 슬퍼.... 

const yearActiveEls = document.querySelectorAll('.year')
let isActiveYear = false;

for (const yearActiveEl of yearActiveEls) { // 반복 가능한 객체에 대해서 반족하는 문법!! 
  
  yearActiveEl.addEventListener('click', function () {
    isActiveYear = !isActiveYear
    if (isActiveYear) {
      // active 클래스 추가
      yearActiveEl.classList.add('active')
    }
    else {
      // active 클래스 제거
      yearActiveEl.classList.remove('active')
    }
    console.log(yearActiveEl.dataset.year)
  })
}

혹시 이게 그냥 반복문이 아니라 차래로 꺼내오기 때문인가 생각했다. 그래서 2중 for문으로도 작성을 하는 등 여러 가지 방법을 시도해 보았지만 계속 class를 지우지 못했다. 

어떻게 하지 고민을 하다가 문득... 원래 2021은 자동으로 선택되어 있고, 다른 것을 클릭하면 바뀌어야 하는 것 같다는 생각이 들었다. 그래서 코드를 바꾸어 보았다. 

 

3. 성공!  

완성 html 코드

<ul class="timeline">
  <li class="year active" data-year='2021'></li>
  <li class="year" data-year='2020'></li>
  <li class="year" data-year='2019'></li>
  <li class="year" data-year='2018'></li>
  <li class="year" data-year='2017'></li>
  <li class="year" data-year='2016'></li>
  <li class="year" data-year='2015'></li>
  <li class="year" data-year='2014'></li>
  <li class="year" data-year='2013'></li>
</ul>

 

완성 js 코드

// HISTORY TIMELINE
const yearEls = document.querySelectorAll('.year')
let isActiveYear = false;


for (let i = 0 ; i < yearEls.length ; i += 1 ) { // 반복 가능한 객체에 대해서 반족하는 문법!!   
  yearEls[i].addEventListener('click', function () {
    isActiveYear = !isActiveYear  
    if (isActiveYear) { // 클릭되었다면!! 
      // 먼저 현재 active 되어있는 객채를 찾아준다. 제일 처음에는 2021을 찾을 것이다!!
      let findActiveEl = document.querySelector('.active')
      // 현재 active 가 있는 요소에서 active 클래스를 제거해준다!
      findActiveEl.classList.remove('active') 
      // 클릭한 요소에 active 클래스를 추가한다!! 
      yearEls[i].classList.add('active')
    }
  })
}

 

정말 삽질 많이 했지만, 그래도 결국에는 성공해서 다행이다. 강사님이 한글로 어떤 코드를 쓰고 싶은지 써보고 코드를 짜라고 했는데, 정말 한글로 어떻게 돌아갈지 주절주절 말하고 난 다음에 코드를 고쳐보니까 코드가 왜 안 돌아가는지 알 수 있었다. 휴..^^ 

이제... 내용을 넣어야한다... 산 넘어 산 같지만 파이팅이다!!! 

댓글