문제상황:
웹 페이지에서 JavaScript를 사용하여 HTML 요소를 다루려고 할 때, 다음과 같은 에러가 발생했습니다.
에러가 발생한 코드:
const btn = document.querySelector("#submitBtn");
btn.addEventListener("click", function () {
// 이벤트 핸들러 코드
});
에러로그 내용:
Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
해결방법:
에러가 수정된 코드:
document.addEventListener("DOMContentLoaded", function () {
const btn = document.querySelector("#submitBtn");
if (btn) {
btn.addEventListener("click", function () {
// 이벤트 핸들러 코드
});
}
});
- DOMContentLoaded 이벤트를 사용하여 DOM이 완전히 로드된 후 코드가 실행되도록 했습니다.
- 버튼이 존재하는지 확인한 후에만 이벤트 핸들러를 등록하도록 했습니다.
원인분석:
이 에러는 JavaScript 코드가 실행되는 시점에 DOM 요소가 아직 로드되지 않아서 발생합니다. 코드는 #submitBtn 요소를 찾으려고 시도하지만, 해당 요소가 아직 존재하지 않기 때문에 null 값을 반환합니다. 따라서 addEventListener 메서드를 호출하려고 할 때, "Cannot read properties of null"이라는 에러가 발생합니다.
이 문제를 해결하기 위해서는 코드 실행 시점을 DOM이 완전히 로드된 이후로 변경해야 합니다. 이를 위해 DOMContentLoaded 이벤트를 사용하여 DOM이 로드된 후에만 이벤트 핸들러를 등록하도록 코드를 수정했습니다. 또한, 요소가 존재하는지 확인한 후에만 이벤트 핸들러를 등록하도록 코드를 변경하여 에러를 예방할 수 있습니다.
에러 발생 원리를 이해하기 위해 아래와 같은 순서도를 그려볼 수 있습니다.
- 웹 페이지 로드 시작
- HTML 요소들이 순차적으로 로드됨
- 자바스크립트 코드 실행
- 에러 발생: "Uncaught TypeError: Cannot read property 'addEventListener' of null"
이 순서도를 통해 알 수 있는 것은, 자바스크립트 코드가 실행되는 시점에 #myButton이라는 요소가 아직 로드되지 않았기 때문에 에러가 발생한다는 점입니다.
이를 해결하기 위해, 다음과 같이 DOMContentLoaded 이벤트를 사용하여 DOM이 완전히 로드된 후에 이벤트 리스너를 추가하는 방법을 사용합니다.
- 웹 페이지 로드 시작
- HTML 요소들이 순차적으로 로드됨
- DOMContentLoaded 이벤트 발생
- 자바스크립트 코드 실행: 이벤트 리스너 추가
- 정상 작동
이렇게 DOMContentLoaded 이벤트를 사용하면, 모든 HTML 요소가 로드된 후에 자바스크립트 코드가 실행되므로 에러를 피할 수 있습니다.