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 메소드 사용 불가능
'트러블슈팅' 카테고리의 다른 글
[MySQL] Docker로 Mac M1에 MySQL 설치하기 (0) | 2023.11.05 |
---|---|
[Spring Boot] Lombok cannot find symbol 에러 (0) | 2023.10.12 |
[Spring MVC] No Mapping for GET WEB-INF/views/main.jsp (0) | 2023.06.26 |
[Servlet] Maven 프로젝트 Tomcat 연동 Servlet 실행하기 (Intellij) (0) | 2023.06.21 |