728x90
Bubbling, Capturing
DOM(Document Object Model) 요소에 이벤트 발생 시, 그 이벤트가 어떻게 전달되는지를 정의하는 방식
이벤트 전파(Event Propagation)
브라우저에서 이벤트 발생 시, 이벤트는 DOM 트리 상에서 여러 단계에 걸쳐 전파된다.
- Capturing Phase (캡처링 단계)
이벤트가 상위 요소에서 하위 요소로 내려오면서 전파 - Target Phase (타깃 단계)
이벤트가 실제로 발생한 요소(target) 에 도달 - Bubbling Phase (버블링 단계)
이벤트가 타깃 요소에서 다시 상위 요소로 전파
이벤트가 발생하면 해당 이벤트는 자식 요소에서 부모 요소로 전파되는 '버블링(bubbling)' 이 일어나게 된다.
버블링 전파 시, 부모 요소에 등록된 이벤트 리스너가 실행될 수 있다.
JS는 기본적으로 버블링이 발생하기 때문에, 의도치 않은 이벤트 실행을 막으려면 버블링을 중지해야 한다
이 때 이벤트 전파를 중단하는 event.stopPropagation() 을 사용하여야 한다
<!-- 예시 코드-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Event Stop Propagation 예제 1</title>
</head>
<body>
<div id="parent" style="padding: 20px; background-color: lightblue;">
부모 요소
<button id="child">자식 버튼</button>
</div>
<script>
// 부모 요소에 클릭 이벤트 리스너 등록
document.getElementById("parent").addEventListener("click", function() {
alert("부모 요소 클릭됨");
});
// 자식 버튼에 클릭 이벤트 리스너 등록
document.getElementById("child").addEventListener("click", function(event) {
event.stopPropagation(); // 부모 요소로 이벤트 전파 차단
alert("자식 버튼 클릭됨");
});
</script>
</body>
</html>
event.preventDefault()
이벤트가 발생했을 때 브라우저가 기본적으로 수행하는 동작을 취소하는 메서드
기본 이벤트를 지우고, 새로운 이벤트를 추가할 경우 주로 사용한다
1. 로그인 폼 처리 (submit 막고 Ajax 요청 보내기)
<form id="loginForm">
<input type="text" name="username" placeholder="아이디" required />
<input type="password" name="password" placeholder="비밀번호" required />
<button type="submit">로그인</button>
</form>
<script>
document.getElementById("loginForm").addEventListener("submit", async function(e) {
e.preventDefault(); // 기본 폼 제출 막기
const formData = new FormData(this);
const data = {
username: formData.get("username"),
password: formData.get("password")
};
try {
const response = await fetch("/api/login", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
});
if (response.ok) {
alert("로그인 성공!");
// location.href = "/dashboard"; // 리다이렉트 가능
} else {
alert("로그인 실패. 다시 시도하세요.");
}
} catch (err) {
console.error(err);
alert("서버 오류 발생");
}
});
</script>
2. 댓글 입력 후 페이지 새로고침 없이 동적으로 추가하기
<form id="commentForm">
<input type="text" name="comment" placeholder="댓글을 입력하세요" required />
<button type="submit">등록</button>
</form>
<ul id="commentList"></ul>
<script>
document.getElementById("commentForm").addEventListener("submit", function(e) {
e.preventDefault(); // 새로고침 방지
const commentInput = this.elements["comment"];
const comment = commentInput.value;
if (!comment.trim()) return;
const li = document.createElement("li");
li.textContent = comment;
document.getElementById("commentList").appendChild(li);
commentInput.value = "";
});
</script>
3. 모바일에서 터치 스크롤 막기
document.addEventListener("touchmove", function(e) {
if (shouldPreventScroll()) {
e.preventDefault(); // 스크롤 방지
}
}, { passive: false }); // passive: false 꼭 넣어야 preventDefault 작동함
function shouldPreventScroll() {
return true; // 예: 특정 모달이 열렸을 때만 true 반환
}
4. 드래그 앤 드롭으로 이미지 업로드 처리
<div id="dropArea" style="width:300px;height:150px;border:2px dashed gray;">파일을 여기로 드래그하세요</div>
<script>
const dropArea = document.getElementById("dropArea");
["dragenter", "dragover", "dragleave", "drop"].forEach(eventName => {
dropArea.addEventListener(eventName, e => {
e.preventDefault(); // 브라우저 기본 동작 방지
e.stopPropagation(); // 이벤트 버블링 중단
});
});
dropArea.addEventListener("drop", e => {
const files = e.dataTransfer.files;
if (files.length > 0) {
console.log("업로드할 파일:", files[0].name);
// 파일 업로드 로직 추가
}
});
</script>
'FrontEnd' 카테고리의 다른 글
[FrontEnd] jQuery 화살표 함수(=>)의 this (0) | 2025.04.10 |
---|---|
[JS] querySelector vs getElement (0) | 2025.04.07 |
[JS] 비동기로 데이터 처리(async/await, fetch then) (0) | 2025.04.01 |
HTML DOM(Document Object Model) (0) | 2025.03.18 |