반응형
이벤트 중첩에 대하여
HTML 태그는 중첩되어 있다. 따라서 특정한 태그에서 발생하는 이벤트는 중첩되어 있는 태그들 모두가 대상이 될 수 있다.
만약 중첩된 HTML 태그들에 이벤트가 등록 되어 있다면 중첩된 이벤트가 어떻게 처리 되는지 확인 할 수있다.
↓
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<style>
html{border:5px solid red;padding:30px;}
body{border:5px solid green;padding:30px;}
fieldset{border:5px solid blue;padding:30px;}
input{border:5px solid black;padding:30px;}
</style>
</head>
<body>
<fieldset>
<legend>이벤트 전파</legend>
<input type="button" id="target" value="target">
</fieldset>
<script>
function handler(event){
var phases = ['capturing', 'target', 'bubbling']
console.log(event.target.nodeName, this.nodeName, phases[event.eventPhase-1]);
}
document.getElementById('target').addEventListener('click', handler, true);
document.querySelector('fieldset').addEventListener('click', handler, true);
document.querySelector('body').addEventListener('click', handler, true);
document.querySelector('html').addEventListener('click', handler, true);
</script>
</body>
</html>
- 위의 코드의 결과를 보면 제일 부모인 HTML부터 차례대로 깊숙이 들어가 taget까지 전파되는 것을 확인 할 수 있다.
- 이렇게 이벤트가 부모에서부터 발생해서 자식으로 전파되고 있는 방식을 캡처링(capturing)이라고 한다.
- ie 낮은 버전에서는 작동하지 않기 때문에 많이 사용하지는 않는다.
- ※ 위 코드에서 this.nodeName의 this는 이벤트 헨들러인 handler의 함수를 호출하게 한 이벤트 타겟인 버튼 input 태그 값을 의미하는 것으로 볼 수 있다.
- ※ eventphase-1 프로퍼티는 이벤트 헨들러인 handler 함수가 호출될 때 만약 capturing의 와중에서 호출된 것이면 숫자 1을 나오게 하여 var phases = ['capturing', 'target', 'bubbling']의 배열의 순서에 따라 'capturing'이 리턴하게 되는 원리이다.
위의 똑같은 코드 중 아래와 같이 addEventLister의 세 번째 인자인 true을 false로 바꾸면 전파 방향이 반대로 나오는 것을 확인 할 수있다.
↓
document.getElementById('target').addEventListener('click', handler, false);
document.querySelector('fieldset').addEventListener('click', handler, false);
document.querySelector('body').addEventListener('click', handler, false);
document.querySelector('html').addEventListener('click', handler, false);
이처럼 캡처링과 다르게 자식부터 부모로 이벤트가 전파되는 것을 버블링(bubbling)이라고 한다.
또 추가하자면 event.stopPropagation()을 아래와 같이 코드를 변경하면 버블링, 캡쳐링 중단하게 할 수 있다.
↓
<script>
function handler(event){
var phases = ['capturing', 'target', 'bubbling']
console.log(event.target.nodeName, this.nodeName, phases[event.eventPhase-1]);
}
function stophandler(event){
var phases = ['capturing', 'target', 'bubbling']
console.log(event.target.nodeName, this.nodeName, phases[event.eventPhase-1]);
event.stopPropagation();
}
document.getElementById('target').addEventListener('click', handler, false);
document.querySelector('fieldset').addEventListener('click', handler, false);
document.querySelector('body').addEventListener('click', stophandler, false);
document.querySelector('html').addEventListener('click', handler, false);
</script>
- 중단시키고자 하는 부분에 addEventListener의 두 번째 인자에 새로 만든 이벤트 헨들러 함수 stophandler을 넣어주었다.
- 결과값을 보면 stophandler 함수를 넣어준 body 부분에서 캡쳐링 이벤트 전파가 중단 된 것을 볼 수 있다.
반응형
'프로그래밍 개발 > JS 웹' 카테고리의 다른 글
Javascript 이벤트 타입 - 폼(form) (0) | 2020.11.26 |
---|---|
Javascript 이벤트 - 기본동작의 취소 (0) | 2020.11.23 |
Javascript 이벤트 - 등록방법 (0) | 2020.11.23 |
Javascript 이벤트 (0) | 2020.11.23 |
Javascript 문서의 기하학적 특성 (0) | 2020.11.23 |
댓글