«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
Recent Posts
Recent Comments
관리 메뉴

뉴히의 개발 로그

javascript addEventListner Err 오류해결 본문

Javascript

javascript addEventListner Err 오류해결

뉴히 2023. 6. 5. 14:32

document.ready

개인과제 프로젝트를 하다가 바로 문제를 만나버림

왜애ㅐㅐㅐㅐㅐㅐㅐㅐㅐㅐㅐㅐㅐㅐㅐㅐㅐㅐㅐㅐ!!!

 

addEventListner 오류는 상황마다 다르고 해결 방법도 다를 수 있겟지만

구글링해보면 여러 해결 방법들이 나와있다.

 

해결 1)

script 코드가 상단<head> 안에 있을경우 HTML이 다 읽히기도 전에 이벤트가 발생하기 때문에, 객체가 무엇인지, 그값을 알 수 없어서 오류가 발생하는 경우가 있다.

 

나같은 경우는 cardList가 null 값이 었고,  script 소스 코드를 body 닫는 태그 위로 옮기니 바로 해결이 되었다. 

html 파싱 후에 script가 동작하니 깔끔히 해결되는 문제였던 것이다!

 

해결2)

이와같은 경우는 script를 상단에 두고도 해결이 가능하다. defer를 추가하는것!

 
<script src="../static/modules/main.js" defer></script>
 

이렇게 추가해둘 경우, html 파서가 윗부분부터 읽으며 script 파일은 다운받아 두지만, 실행은 파싱이 완료된 후에 하기 대문에 위같은 오류는 발생하지 않는다!

 

 
<script src="../static/modules/main.js" type="module" ></script>
 

또한 모듈화를 진행하면, type ="module" 을 넣어주면, defer와 use strict도 함께 적용된다.

 

 

위 두개의 방법은 스크립트가 읽히는 순서때문에 일어난 해결 방법이라면

해결 3은 여러개를 읽을때?의 차이 점때문의 해결 방법이다...(말이 디게 이상한....)

 

 

해결3)

//HTML

<ul>
	<li class="card-list"></li>
	<li class="card-list"></li>
	<li class="card-list"></li>
	<li class="card-list"></li>
</ul> 


// script

let cardList = document.getElementsByClassName('card-list');
console.log(cardList);
cardList.addEventListener("click", function(){    
    console.log("!!!!!!!!!!!!");
});

 

이런 경우는 해결방법을 서칭하다가 알게된 것인데

DOM을 제어하기 위해 선언한 getElementsByClassName() 의 경우 객체를 배열로 출력하기에 발생한 문제라고한다

 

해결 3-1) 해당 클래스 중 하나만 사용 할때

이럴때 배열 객체중 하나만 뽑아서(인덱스 번호를 넣어서) 사용이 가능하다.

 
cardList[0].addEventListener('click', function () {
                console.log('!!!!!!!!!!!!');
            });
 

 

해결 3-2) 해당클래스 모두 적용 할때

 

getElementsByClassName vs querySelectorAll 둘의 차이가 있다!
두 함수 모두 DOM 의 class 명을 가져올 수 있는 함수이나 HTMLCollection 형식인지 NodeList 형식인지의 차이가 있다!


1. HTMLCollection (getElementsByClassName 사용 시)
 - live DOM 즉 객체의 상태 변화를 실시간으로 반영하는 함수.

2. querySelectorAll
 - non-live 즉 객체의 상태 변화를 정적으로 반영하는 함수.

이중 querySelectorAll 활용 시 array.forEach 를 사용할 수 있다고 한다.
제일좋은건 두 객체 모두 배열로 변환 후 사용하는것이 권장된다고 하니 기억해두자.
=> Array.from과 스프레드 연산자를 활용하면된다.

getElementsByClassName 으로 썻을때 cardList
querySelectorAll을 썻을때 cardList

 

 

해결 방법

<ul style="font-size: 50px">
    <li class="card-list">d</li>
    <li class="card-list">d</li>
    <li class="card-list">d</li>
    <li class="card-list">d</li>
</ul>

<script>
    let cardList = document.querySelectorAll('.card-list');
    console.log(cardList);
    cardList.forEach((e) => {
        e.addEventListener('click', function (e) {
            console.log('!!!!!!!!!!!!');
        });
    });
</script>

getElementsByClassName => querySelectorAll 으로 변경 후 forEach() 반복문을 활용하여 원하는 결과를 도출할 수 있다

 

 

참고 : https://jae1590.tistory.com/184