classList.toggle과 querySelectorAll 사용 예제

2021. 8. 24. 19:38JavaScript

 

별 아이콘의 색이 채워졌다 사라졌다 하는 효과를 버튼에 클릭 이벤트가 발생할 때마다 적용시키고 싶었다

처음에 querySelector를 생각했다가 생각해보니 카드가 하나만 생기는 게 아닌 여러 개의 카드가

계속해서 추가될 예정이라 (=> 별 아이콘의 개수도 똑같이 늘어남) 일반적인 querySelector를 사용했더니

맨 처음에 찾아진 starIcon 클래스에만 적용이 되었다.

 

그래서 querySelectorAll을 사용했다

처음에 querySelectorAll을 사용하면 반복문이 가능한 유사배열인 Nodelist가 반환된다는 걸 생각 못해서

왜 계속 에러가 나는거지.. 했었는데 같은 조원인 친구가 알려줬다 (..!)

 

<button>
	<i class="starIcon far fa-star"></i>
</button>

 

코드의 마크업 부분이다

여기서 아이콘의 변화는 class에 far가 있을 경우엔 바탕색이 채워지지 않은 노란색 별 아이콘이 보이고,

class에 fas가 추가될 경우 바탕색이 노란색으로 채워진 별로 바뀐다

 

let icons = document.querySelectorAll('.starIcon');

for (let i=0; i < icons.length; i++) {
    icons[i].addEventListener('click', ()=> {
        icons[i].classList.toggle('fas');
    });
}

 

 

starIcon class가 있는 <i> 태그에 for 반복문을 적용시켰다

여기서 icons는 배열로 출력되기 때문에 모든 nodelist의 아이템을 선택하려면 for 반복문으로 인덱스[i] 만큼 반복해서

뽑아줘야 한다

 

classList.toggle은 지정한 클래스의 클래스명이 존재하면 삭제, 존재하지 않으면 추가해준다

그래서 위 코드의 경우  icons [i]의 클래스에 fas가 없다면 추가해주고, fas가 있다면 삭제해준다

클릭이벤트가 발생할 때마다 변경이 되어 모든 starIcon에 클릭이벤트가 적용이 된다

 

위의 코드외에도 이벤트 타깃을 잡아서

 

let icons = document.querySelectorAll('.starIcon');

for (let i=0; i < icons.length; i++) {
    icons[i].addEventListener('click', (e)=> {
        e.target.classList.toggle('fas');
    });
}

 

 

이렇게도 작성이 가능하다.

 

원래  icons[i]의 위치에 this를 넣을 생각이었는데 에러가 났다

 

 

 

 

this를 콘솔창에 출력해보니 내가 생각 한 <i> 태그가 아닌 window가 이벤트 타깃으로 잡혀있었다

블로그에 적혀있는 설명글을 읽었는데 아직 왜 this가 window를 타깃으로 잡고 있는지 모르겠다..

icons에 addEventListener를 적용시켰는데 🤔

왜그런지 찾아보고 다시 정리해봐야겠다

 

 

+

 

 

-> 원인은 arrow function ()=> {}이었다

원래 일반적인 함수 선언의 경우 (함수 표현식 함수 선언식) this를 감싸고 있는 스코프에 따라 this가 무엇을 상속받는지가

바뀌는데 여기선 arrow function을 사용하여 가장 상위의 this를 상속받게 되는 것이었고 그래서 window가 타깃으로

잡혔던 거였다!

 

let icons = document.querySelectorAll('.starIcon');


for (let i=0; i < icons.length; i++) {
    icons[i].addEventListener('click', function() {
        this.classList.toggle('fas');
    });
}

 

그래서 arrow function이 아닌 함수 선언식을 이용하여 작성했고

 

 

 

작성 후 콘솔 창으로 this를 확인해보니 i태그가 잘 출력되고 있다

🥳

 

 

반응형