문제 상황
- 바닐라JS로 모달을 만들며 dom을 가져와 이벤트리스너를 달아주고있었습니다.
- 본격적으로 모달을 만들기 전, 이벤트가 잘 달리는지 확인을 위해 단순히 이벤트리스너를 다는 코드를 구현했는데 다음과 같은 에러가 발생했습니다.
문제 발생 코드
<head>
<meta charset="UTF-8">
<title> 상세페이지 </title>
<script>
const openButton = document.getElementById("delete");
function alertFunc() {
console.log("hi");
alert("hihi");
}
openButton.addEventListener("click", alertFunc);
</script>
</head>
<body>
<button id="delete"> 삭제 </button>
</body>
원인 파악
- 위 에러는 addEventListener을 실행하던 도중 이벤트를 추가할 돔 요소가 null이기에 발생한 에러였습니다.
- 이에 저는 document.getElementById("delete")를 실행 하는 과정에서 돔을 찾지 못한 것이라 판단했습니다.
- 코드가 잘못되었나 ?
- 그러나 document.getElementById("delete") 코드 및 button 태그 자체에는 문제가 없었습니다.
- 그럼에도 delete버튼 노드의 값이 null이라는 것은, 아직 브라우저가 DOM 생성을 완료하지 않은 상태에서 delete 버튼 노드를 가져오려 했기에 발생한 에러라 유추했습니다.
- script 태그의 위치 문제인가?
- 브라우저는 HTML 페이지를 파싱하는 중 script 코드를 만나면 DOM 생성을 멈추고 스크립트 파일을 다운로드 됩니다.
- 그리고 스크립트 파일이 다운로드 완료되고 나서야 파싱을 재개합니다.
- 문제가 발생한 코드는 script태그가 head태그 내에 있었습니다.
- 따라서 body 태그에 있는 삭제 버튼이 파싱되어 돔에 추가 되기 이전에 script가 다운로드 및 실행되었고, 이 과정에서 해당 에러가 발생한 것 같다는 판단이 들었습니다.
이에 대한 해결방안으로는 2가지가 있습니다.
- DOM 생성을 완료한 후 script가 실행되도록 script 태그를 body 태그 맨 아래에 위치 시킨다.
- “DOMContentLoaded”라는 리스너를 document에 추가한다.
사실 두 가지 방안 모두 DOM 생성을 완료한 후 스크립트 태그에 있는 자바스크립트 코드가 실행되도록 하는 방법입니다.저같은 경우 html 파일의 가독성을 위해 두 번째 방안을 선택했습니다.
해결방안
script 태그 안에서 실행할 js 코드를 아래 함수 안에 넣어준다. (body태그 맨 아래에 script 태그를 위치시켜도 동일하게 해결됩니다 !)
document.addEventListener("DOMContentLoaded", function() {
/*
script 태그 안에 실행할 js 코드
*/
});
<head>
<meta charset="UTF-8">
<title> 상세페이지 </title>
<script>
document.addEventListener("DOMContentLoaded", function() {
const openButton = document.getElementById("delete");
function alertFunc() {
alert("삭제버튼 클릭");
}
openButton.addEventListener("click", alertFunc);
});
</script>
</head>
<body>
<button id="delete"> 삭제 </button>
</body>
해결 !!
'💛 Javascript' 카테고리의 다른 글
[JS] 제에모옥은 Javascript 문법 모음집으로 하겠습니다... 그런데 이제 알고리즘을 곁들인... (0) | 2024.12.30 |
---|---|
[JS] Array와 메서드 등에 대해 알아보자 (6) | 2024.07.15 |