[JavaScript] addEventListener is not a function

0. 배경

- HTML, CSS, JS로 간단 자기소개서 만들기

- 텍스트에 mouseover해서 색상 바꾸고, mouseout하면 원래 색상으로 돌아가기

- getElementsByClassName()으로 'main_item_container' 클래스의 element 가져와서 타겟으로 하기

 

1. 문제 상황

# jeonsoyeong.html

        <ul class="main_items_container">
            <li class="main_item_container">
                전소영
            </li>
        </ul>

 

addEventListener is not a function 에러 발생

# jeonsoyeong.js

var contents = document.getElementsByClassName("main_item_container");
contents.addEventListener("mouseover", function(event) {
    event.target.style.color = "pink";
}, false);

 

2. 해결 과정

- console.log(contents)로 찍어보니 배열

- getElementsByClassName()을 사용할 경우, 해당 class에 해당하는 element가 여럿임으로 배열로 출력됨

방법 1. DOM 객체 중 하나만 적용하고 싶은 경우

var contents = document.getElementsByClassName("main_item_container");
contents[0].addEventListener("mouseover", function(event) {
    event.target.style.color = "pink";
}, false);

- 몇 번째 element에 적용하고 싶은지 인덱스 지정해주기

 

방법 2. DOM 객체 중 해당 클래스 모두에 적용하고 싶은 경우

var contents = document.getElementsByClassName("main_item_container");
contents.forEach((element) => {
        element.addEventListener("mouseover", function(event) {
            event.target.style.color = "pink";
        }, false);
    })

- forEach()로 element 하나씩 꺼내서 적용하기

 

Cannot read properties of undefined (reading 'addEventListener') 에러 발생

- forEach()로 바꿔도 또다른 에러가 발생했음..

- getElementByClassName()으로 찾은 객체는 forEach() 적용 불가능하다고 함

- querySelectorAll()로 가져와서 forEach() 사용해야 함

- querySelectorAll() 안에 클래스를 나타내는 '.'을 포함해야 함 (이거 안해줘서 삽질 agian..)

    var contents = document.querySelectorAll(".main_item_container")

    contents.forEach((element) => {

        element.addEventListener("mouseover", function(event) {
            event.target.style.color = "pink";
        }, false);
    
        element.addEventListener("mouseout", function(event) {
            event.target.style.color = "white";
        }, false);
    })

- 근데 또 아무것도 가져오지 못했고.....ㅠ

 

https://jae1590.tistory.com/184

 

[JavaScript] addEventListener 작동오류 (addeventlistener is not a function)

특정 위치에 마우스를 올리면 버튼 색에 변화를 주려는 코드를 작성하던 중 addEventListener가 작동을 안한다..?! 원일을 파악해보니 DOM을 제어하기 위해 선언한 getElementsByClassName() 의 경우 객체를

jae1590.tistory.com

 

window.onload() 사용하기

-elements를 로드해오기 전에 class를 찾도록 해서 아무것도 가져오지 못했음

- window.onload()를 사용해서 웹 브라우저의 모든 elements를 로드해온 후, 해당 class를 찾도록 변경해주었음

window.onload = function() {
    var contents = document.querySelectorAll(".main_item_container")

    contents.forEach((element) => {

        element.addEventListener("mouseover", function(event) {
            event.target.style.color = "pink";
        }, false);
    
        element.addEventListener("mouseout", function(event) {
            event.target.style.color = "white";
        }, false);
    })
}

 

3. 원인

- getElementByClassName과 querySelectorAll를 구분하여 쓰자

getElementsByClassName

- HTMLCollection 반환

- HTMLCollection은 Live DOM 컬랙션 객체, 내부 원소(노드)에 변화가 생기면 이를 즉시 반영함

- .item, .namedItem 메소드 사용 가능

- .forEach, .map 메소드 사용 불가능

 

querySelectorAll

- NodeList 반환

- NodeList는 Non-Live DOM 컬랙션 객체, 원소(노드)의 변화를 즉시 반영하지 않음

- .item, .forEach 메소드 사용 가능

- .filter, .map 메소드 사용 불가능