한 요소에 이벤트가 발생하면 해당 요소의 이벤트를 처리하고 부모요소의 이벤트가
다음에 실행됩니다.
가장 최상단의 부모요소의 이벤트를 만날 때 까지, 이벤트가 존재하는 모든 부모요소의
이벤트를 한 번씩 수행합니다.
⛔
focus
이벤트와 같이 버블링 되지 않는 이벤트도 있습니다. 몇몇 이벤트를 제외하곤
대부분의 이벤트는 버블링 됩니다.
<body>
<p onclick="alert('단락')">
textsts
<button onclick="alert('버튼')">Click</button>
</p>
</body>
⭐ 이벤트 발생
event.stopPropagation()
이벤트 객체 메서드를 사용해서 버블링을 중단할 수 있습니다.<head>
생략
<style>
.hide {
display: none;
}
</style>
<title>Poketmon Demo</title>
</head>
<body>
<div id="container">
Click To Hide
<button>Change Color</button>
</div>
<script src="./app.js"></script>
</body>
const button = document.querySelector('button');
const container = document.querySelector('#container');
button.addEventListener('click', function () {
container.style.backgroundColor = randomColor();
})
container.addEventListener('click', function () {
container.classList.toggle('hide');
})
/* 랜덤색상 추출 함수 */
const randomColor = () => {
const r = Math.floor(Math.random() * 256);
const g = Math.floor(Math.random() * 256);
const b = Math.floor(Math.random() * 256);
return `rgb(${r},${g},${b})`
}
⭐ 이벤트 버블링으로 인해 컨테이너안의 모든 요소는 클릭 시 요소가 숨겨집니다.
버튼 요소를 클릭했을 때, 요소가 숨겨지지 않고 색상이 변경되려면 부모요소의 버블링을
중단해야 한다.
const button = document.querySelector('button');
const container = document.querySelector('#container');
/* 이벤트 객체를 이용해서 버블링 중단 */
button.addEventListener('click', function (e) {
container.style.backgroundColor = randomColor();
e.stopPropagation(); // 부모요소의 이벤트에 영향을 받지 않습니다.
})
container.addEventListener('click', function () {
container.classList.toggle('hide');
})
const randomColor = () => {
const r = Math.floor(Math.random() * 256);
const g = Math.floor(Math.random() * 256);
const b = Math.floor(Math.random() * 256);
return `rgb(${r},${g},${b})`
}
⭐ 이벤트 버블링이 중단되어 부모요소의 이벤트가 발생하지 않습니다.!
<body>
<h1>Form Event !</h1>
<form action="/dogs" id="commentForm">
<input type="text" name="username" placeholder="username">
<input type="text" name="comment" placeholder="comment">
<button>Post Comment</button>
</form>
<h2>Comment :</h2>
<ul>
<!-- 클릭 시 삭제될 li 요소 -->
<li>hey</li>
<li>hey</li>
</ul>
<script src='./app.js'> </script>
</body>
const lis = document.querySelectorAll('li');
const commentForm = document.querySelector('#commentForm');
const ul = document.querySelector('ul');
/* li 요소를 클릭 시, 삭제 이벤트 발생 */
for (let i of lis) {
i.addEventListener('click', () => {
i.remove();
})
}
commentForm.addEventListener('submit', (e) => {
e.preventDefault();
/* 변수 및 함수 수정 */
const userName = commentForm.elements.username;
const userComment = commentForm.elements.comment;
newComment(userName.value, userComment.value);
/* 입력필드 초기화 */
userName.value = '';
userComment.value = '';
}
)
/* 댓글 생성 함수 */
function newComment(userName, userComment) {
/* li 태그와, 컨텐츠를 강조해줄 b 태그 생성 */
const newComment = document.createElement('li');
const bTag = document.createElement('b');
bTag.append(userName);
newComment.append(bTag);
newComment.append(` : ${userComment}`);
ul.append(newComment);
}
⭐ 이벤트 수신기는 처음부터 존재하는
li
요소에 대해서는 작동하지만 새로 추가되는
li
요소에 대해서는 이벤트가 발생하지 않습니다.
즉, 추후에 추가될 요소에 대해서는 이벤트가 발생하지 않는다.
target
속성을const commentForm = document.querySelector('#commentForm');
const ul = document.querySelector('ul');
ul.addEventListener('click', (e) => {
console.log('click');
console.log(e);
});
commentForm.addEventListener('submit', (e) => {
e.preventDefault();
/* 변수 및 함수 수정 */
const userName = commentForm.elements.username;
const userComment = commentForm.elements.comment;
newComment(userName.value, userComment.value);
/* 입력필드 초기화 */
userName.value = '';
userComment.value = '';
}
)
/* 댓글 생성 함수 */
function newComment(userName, userComment) {
/* li 태그와, 컨텐츠를 강조해줄 b 태그 생성 */
const newComment = document.createElement('li');
const bTag = document.createElement('b');
bTag.append(userName);
newComment.append(bTag);
newComment.append(` : ${userComment}`);
ul.append(newComment);
}
⭐ 이벤트를 적용한것은
ul
요소지만, 이벤트 객체안에target
속성을 확인해서
사용자가ul
요소안에 어떤 요소를 클릭했는 지 확인할 수 있다.
확인을 해야하는 이유는ul
요소안에li
요소이외에 다른 요소가 있을수도 있기에
타겟을 확인하고, 해당 타겟이 지워야될 요소가 맞다면 속성을 사용하면 됩니다.
const commentForm = document.querySelector('#commentForm');
const ul = document.querySelector('ul');
ul.addEventListener('click', (e) => {
console.dir(e.target); // 클릭한 요소의 태그명을 확인
});
/* 생략 */
⭐
nodeName
속성을 사용해서 사용자가 클릭한 요소가 지워야할 요소가 맞는지
비교하고 필요한 요소만 삭제할 수 있습니다.
const commentForm = document.querySelector('#commentForm');
const ul = document.querySelector('ul');
ul.addEventListener('click', (e) => {
e.target.nodeName === 'LI' && e.target.remove();
// 노드명이 'LI'가 맞는 경우에만 우측의 피 연산자(remove)를 수행한다
});
/* 생략 */
⭐ 이렇게
nodeName
을 이용해서 삭제해야될 요소만 삭제하고, 삭제하지 말아야할
불필요한 요소는 이벤트 발생을 막을 수 있습니다.