DOM #2 이벤트

jhyun_k·2022년 10월 19일
1
post-thumbnail

이벤트 객체

이벤트에서 호출되는 핸들러에는 이벤트와 관련된 모든 정보를 가지고 있는 매개변수가 전송되는데 이것이 바로 이벤트 객체이다

<article class="parent">
    <ol>
        <li><button class="btn-first" type="button">버튼1</button></li>
        <li><button type="button">버튼2</button></li>
        <li><button type="button">버튼3</button></li>
    </ol>
</article>
const btnFirst = document.querySelector('.btn-first');
btnFirst.addEventListener('click', (event) => {
    console.log(event);
});
  • JS에서 이벤트는 객체 형식으로 정보가 저장되어 이벤트가 타깃으로 하는 객체(DOM, Document, Window 등)로 보내진다. 이때 이벤트의 정보를 저장하는 객체가 이벤트 객체인 것이다.

  • 이벤트가 타깃으로 하는 객체는 EventTarget 인터페이스를 따르는 객체로 이벤트를 수신할 수 있고 수신한 이벤트에 대해 이벤트 핸들러를 가질 수 있는 객체 ex) Element, Document, Window 등

    addEventListener 메서드 방식

    addEventListener 메서드 방식은 3개의 매개변수를 가진다.
    addEventListener(이벤트 타입, 이벤트 핸들러, 이벤트 전파단계)

    • 첫 번째 매개변수는 이벤트 타입이다. on 접두사를 사용하지 않는다.
    • 두 번째 매개변수는 이벤트 핸들러다.
    • 마지막 매개변수는 이벤트 전파 단계이다. 기본값이 bubbling이므로 생략하면 버블링 단계에서 이벤트를 캐치한다. true 값을 지정할 경우 캡쳐링 단계에서, false값을 지정할 경우 버블링 단계에서 이벤트를 캐치하게 된다
    h1.addEventListener('click',function () {
    	console.log('클릭했습니다.');
    });
    // addEventListener(이벤트 타입, 이벤트 핸들러, 이벤트 전파단계)

이벤트 흐름

브라우저 화면에서 이벤트가 발생하면 브라우저는 가장 먼저 이벤트 대상(event target)을 찾는다

  • 캡쳐링 단계
    : 브라우저가 이벤트 대상을 찾아갈 때는 가장 상위의 window 객체부터 document, body 순으로 DOM 트리를 따라 내려가는데 이를 캡쳐링 단계라고 한다
  • 이벤트 대상을 찾아가는 과정에서 브라우저는 중간에 만나는 모든 캡처링 이벤트 리스너를 실행시킨다
  • 버블링 단계
    : 이벤트 대상을 찾고 캡처링이 끝나면 이제 다시 DOM 트리를 따라 올라가며 만나는 모든 버블링 이벤트 리스너를 실행하는데 이를 이벤트 버블링 단계라고 한다.

    이벤트 객체가 전파되는 방향에 따라 이벤트 전파를 3단계로 구분한다.
  • 첫 번째인 캡처링 단계는 이벤트가 상위 요소에서 하위 요소 방향으로 전파하는 것이고
  • 타깃 단계는 이벤트가 이벤트 타깃에 도달하는 것이다.
  • 마지막으로 버블링 단계는 이벤트가 하위 요소에서 상위 요소 방향으로 전파하는 것을 말한다.
  • 이러한 과정에서 이벤트 리스너가 차례로 실행되는것을 이벤트 전파(event propagation)라고 한다.

이벤트 버블링

최하위 요소부터 시작해 최상위 요소인 Window에 도달할 때까지 이벤트를 지속한다. 대부분의 이벤트는 버블링이 기본 동작이다

<div class="box1">
	box1
	<div class="box2">
		box2
		<div class="box3">
			box3
		</div>
	</div>
</div>
const boxes = document.querySelectorAll('div');
	boxes.forEach(function(div) {
	div.addEventListener('click', boxEvent);
	});
function boxEvent(event) {
	console.log(event.currentTarget.className);
}

이 경우에 가장 하위 요소인 box3를 클릭할 경우 이벤트 리스너가 작동하면서 상위 요소인 부모 요소에 등록된 클릭 이벤트 리스너가 box3, box2, box1 순서대로 실행된다. box2를 클릭하는 경우에는 box2부터 box1까지 이벤트가 실행된다.

이벤트 캡쳐링

최상위 요소인 Window에서 시작해 Document와 HtmlElement를 거쳐 이벤트가 최하위 요소에 도달할 때까지 지속한다.

  • 캡처링 단계에서 이벤트를 실행하고자 할 때는 addEventListener 세 번째 인수에 capture: true 값을 넣어준다. capture의 기본 값은 false 이므로 false를 전달하는 경우에는 타깃 단계와 버블링 단계의 이벤트만 실행한다.
<div class="box1">
	box1
	<div class="box2">
		box2
		<div class="box3">
			box3
		</div>
	</div>
</div>
const boxes = document.querySelectorAll('div');
boxes.forEach(function(div) {
	div.addEventListener('click', boxEvent, {
		capture: true // 캡처링을 동작하게 하는 옵션
	});
});
function boxEvent(event) {
	console.log(event.currentTarget.className);
}

이벤트 전파 방지 방법

preventDefault()

브라우저는 HTML 태그를 통해 여러가지 기능들을 제공하지만 때때로 그러한 기능이 방해가 되는 경우 preventDefault() 메서드를 통해 기본 동작을 중지할 수 있다
preventDefault 메서드는 이벤트 뿐만 아니라 요소의 기본 동작을 중지한다.

  • 예를들면 a 요소를 클릭하면 href라는 a요소의 기본 속성에 따라 해당 링크로 이동한다. 하지만 preventDefault 메서드를 호출해 a 요소의 기본 동작을 중지할 수 있다.
document.querySelector('a').onclick = e => {
	event.preventDefault();
};
  • 버튼도 기본 동작은 submit 이지만 preventDefault() 메서드를 이용하면 이러한 기본 동작을 중지할 수 있다

stopPropagation()

preventDefault를 통해 브라우저의 기본 이벤트 동작을 취소할 수 있지만 이벤트 전파를 막지는 못한다 만약 이벤트 전파를 막고 싶다면 event.stopPropagation() 코드를 추가하면 된다

  • stopPropagation 메서드는 이벤트가 버블링 단계와 캡처링 단계에서 전파되는 것을 방지한다. 전파를 방지해도 이벤트의 기본 동작은 실행되며 stopPropagation 메서드는 동일한 이벤트 대상에서 다른 이벤트 리스너는 멈추지 않는다.
p.addEventListener('click', () => {
 event.stopPropagation(); // 이벤트 전파 중지
 console.log('이벤트 전파 중지의 p 클릭');
});   

이런 식으로 사용

이벤트 위임

이벤트 위임은 이벤트 전파를 활용하여 상위 DOM요소에 이벤트 핸들러를 등록하는 것이다. 하위 DOM 요소에 각각 여러개의 이벤트 핸들러를 등록할 필요 없이 상위에만 이벤트 핸들러를 등록하면 코드가 더욱 간결해질 수 있고 이벤트 리스너가 없어도 마치 리스너가 있는 것 처럼 사용 할 수 있다.

하지만 이벤트위임때는 제대로 안들어서 추후 정리 예정....... 😥

0개의 댓글