⊙ 이벤트 버블링 :
● 개념1 : 이벤트 버블링 정의
○ 정의 : 특정 요소노드에서 이벤트 핸들러가 작동될 시, 이벤트 객체(event)가 이동되는 과정 중 하나를 의미하여, 더 자세히는 그 과정 중 특정 태그부터 부모 태그 .... 맨 상위 노드로 이동되는 단계를 일컫는 말이다.
-Ex :
● 개념2 : 버블링 단계일 때, event객체는 이동하지만. event 객체의 target객체 값은 변하지 않는다!!
○ 설명 :
<li>태그인 item3에서 event 발생시, 버블링 단계 괴정으로 event의 이동과 그 시점에서의 event.target값은 다음과 같다.
- event객체 : item3 //<li>태그 => list // <ul>태그 => content // <div> 태그 => ... window 태그
- event.target값 : item3 요소노드 => item3 요소노드 => item3 요소노드 => ....=> item3 요소노드 (즉, 이벤트발생지점 태그에서 변하지 않는다. )
○ event의 currentTarget 프로퍼티 : event객체가 현재 있는 지점의 태그값을 반환하는 프로퍼티이다.
- event객체 : item3 //<li>태그 => list // <ul>태그 => content // <div> 태그 => ... window 태그
- event.target값 : item3 요소노드 => item3 요소노드 => item3 요소노드 => ....=> item3 요소노드
- event.currentTarget : <li>태그값 => <ul>태그값 => <div>태그값 => ....
● 개념2 : 이벤트 흐름
○ 정의 : 특정 태그에서 이벤트 발생 시, DOM 트리구조에서 이벤트 객체의 모든 이동 과정을 의미한다.
○ 이벤트흐름은 3가지 단계로 분류할 수 있다.
단계1_Capturing 단계 : event객체가 상위노드에서 하위노드로 이동되는 과정을 의미
단계2_Target 단계 : event객체가 이벤트가 발생되는 자점 태그로, 이벤트가 실제요소로 전파하는 과정을 의미
단계3_Bubbling 단계 : event객체가 하위노드에서 상위노드로 이동되는 과정을 의미
○ ★이벤트 흐름을 alert()메소드를 이용하여, 구현해보기
- 상황 :
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
<title>JS with Codeit</title>
</head>
<body>
<div id="content">
content
<h1 id="title">오늘 할 일</h1>
<ol id="list">
list
<li class="item">자바스크립트 공부</li>
<li class="item">유튜브 시청</li>
<li class="item">저녁 약속</li>
<li class="item">독서</li>
<li class="item">일기</li>
</ol>
</div>
<script src="index.js"></script>
</body>
</html>
body * {
padding: 7px 10px;
margin: 5px 8px;
color: #ffffff;
font-size: 12px;
background-color: rgba(0, 0, 0, 0.4);
}
h1 {
font-size: 20px;
font-weight: 500;
}
- 요구사항 :
해당 list를 마우스 왼쪽 클릭을 했을 시 , Capturing 단계, Target 단계, Bubbling 로 alert()로 event가 위치하는 해당 태그 이름이 출력되도록 JavaScript코드를 작성해라.
- 해설 :
①. 버튼을 누를시 , 경고창이 뜨도록 하는 function 부터 작성,선언
②. Capturing 단계와 Bubbling 단계는 SelectorAll(*)로 하여 addEventListener로 이벤트 핸들러 등록함
- Capturing 단계 : addEventListener('click', Alert, true);
- Bubbling 단계 : addEventListener('click', Alert);
③. target단계는 그냥 각 해당하는 태그(요소노드)에만 addEventListener로 등록하면 된다.
- 정답 JavaScript코드 :
const content = document.querySelector('#content');
const list = document.querySelector('#list');
//Capturing 단계
function Alert(event) {
alert(event.currentTarget.tagName);
}
/*
for (let i of document.querySelectorAll('*')) {
i.addEventListener('click', Alert, true);
}
*/
//Bubbling 단계
for (let i of document.querySelectorAll('*')) {
i.addEventListener('click', Alert);
}
/*target 단계*/
//그냥 리스트만 클릭시, target지점만 alert 창 나오도록 함
/*
for(let i=0;i<list.children.length;i++)
{
list.children[i].addEventListener('click',Alert);
}
*/
● 개념3: event 객체 프로퍼티 메소드인 stopPropogation()메소드
# 상황 :
○ 설명 :
각 해당 태그를 클릭시, event객체가 Target시점부터 부모노드까지 이동된 경로의 태그 구성이 출력된다는 메소드를 이벤트 핸들러로 등록했다고 가정하자.
// 이벤트 버블링 (Event Bubbling)
const content = document.querySelector('#content');
const title = document.querySelector('#title');
const list = document.querySelector('#list');
const items = document.querySelectorAll('.item');
content.addEventListener('click', function(e) {
console.log('content Event');
console.log(e.currentTarget);
});
title.addEventListener('click', function(e) {
console.log('title Event');
console.log(e.currentTarget);
});
list.addEventListener('click', function(e) {
console.log('list Event');
console.log(e.currentTarget);
});
○ 출력 :
- Content를 'Click' 할 시 : 'content Event' 출력
- title를 'Click' 할 시 : 'title Event' 출력 => 'content Event' 출력
- list(ul태그)를 'Click' 할 시 : 'list Event' 출력
=>'title Event' 출력=> 'content Event' 출력 - ★item 를 'Click' 할 시 : 'list Event' 출력 => 'content Event' 출력
※ item 태그에다 addEventListener로 이벤트 핸들러 등록을 안했는데, 왜 출력이 되지?
=> item 태그도 ul태그 영역 안에 있기에, ul 태그의 함수가 작동된 것이다. //나중에 쓸모있는 활용점이 되는 개념임
○ 요구사항 :
item 태그를 클릭시에는 자기 타겟만 출력되도록 하고 싶다.
=> addListener()로 이벤트 등록 + 핸들링안 에 event.stopPropogation() 를 추가한다.
● event의 프로퍼티 메소드 stopPropogation()
○ 정의 : event발생 타겟 지점에서 부터 event 객체의 Bubbling 단계(상위노드로의 이동)을 멈추게 하는 메소드다.
○ 주의 : 되도록 안쓰도록 한다. //이유는 자세하게는 모르겠다.
○ 활용 사례 :
const content = document.querySelector('#content'); //상위 div 태그 요소 노드
const list = document.querySelector('#list'); //상위 ul 태그 요소 노드
const li = list.children[2]//ul 내부 3번째 li 태그
//target 단계만 TagName이 출력되도록 한다.
content.addEventListener('click',funtion(event){
console.log(event.tagName);
});
list.addEventListener('click',funtion(event){
console.log(event.tagName);
});
li.addEventListener('click',funtion(event){
console.log(event.tagName);
event.stopPropogatation();
//위의 상위노드들 출력 메소드가 작동되지 않는다.
//엄밀히 말하면, event객체는 li태그에서 부모노드로 이동되지 않아서, 작동이 되지 않는 것
});
◎ 연습문제 :
다음 HTML 코드를 보고 아래의 문제를 해결해 주세요.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>오늘 할 일</title>
</head>
<body>
<div id="main">
<h2 id="title">오늘 할 일</h2>
<ul id="to-do-list">
<li class="item">자바스크립트 공부하기</li>
<li class="item">고양이 화장실 청소하기</li>
<li class="item">고양이 장난감 쇼핑하기</li>
</ul>
</div>
<script src="index.js"></script>
</body>
</html>
const main = document.querySelector('#main');
const toDoList = main.lastElementChild;
function printCurrentTarget(event) {
console.log(event.currentTarget);
}
main.addEventListener('click', printCurrentTarget);
for (let child of toDoList.children) {
child.addEventListener('click', printCurrentTarget);
}
질문 1
아래와 같이 코드를 작성한 다음 프로그램을 실행했습니다. 다음 중 웹 페이지에 나타나는 자바스크립트 공부하기를 클릭했을 때 콘솔에 출력되는 결과는?
○ 해설 :
- 이벤트 핸들러가 등록된 태그 :
- 따라서, 아래 사진과 같이 event 경로 와 작동 순서로 ①, ② 순으로 이벤트 메소드가 작동된다.
○ 정답 :
<li class="item">자바스크립트 공부하기</li>
<div id="main"> <h2 id="title">오늘 할 일</h2> <ul id="to-do-list"> <li class="item">자바스크립트 공부하기</li> <li class="item">고양이 화장실 청소하기</li> <li class="item">고양이 장난감 쇼핑하기</li> </ul> </div>
'CodeIt_Sprint > JavaScript_중급' 카테고리의 다른 글
(8)JavaScript중급_3_5_event 객체의 프로퍼티 메소드 : preventDefault() (0) | 2024.11.13 |
---|---|
(7)JavaScript중급_3_4_이벤트 위임 문제 , 해결방법은 if조건절 + event.contains() 메소드 (5) | 2024.11.13 |
(5)JavaScript중급_3_2_이벤트객체 (0) | 2024.11.13 |
(4)JavaScript중급_3_1_이벤트핸들러 등록 (0) | 2024.11.13 |
(2)JavaScript중급_2_DOM객체_개념부분(이론요약)[작성중..] (0) | 2024.11.11 |