[20231227 TIL] DOM Event / target vs CurrentTarget

Haizel·2023년 12월 27일
1
post-thumbnail

01. DOM Event

이벤트(event) 인터페이스는 DOM에서 발생하는 이벤트로, 사용자의 동작 혹은 프로그램에서 발생하는 특정한 상황을 의미한다.

이벤트 발생 → 사전에 정의된 특정 코드 실행 → 그 결과로 기능이 동작하거나, 화면이 변경되는 등의 변화 발생


✴︎ HTML Event

HTML에서 발생하는 이벤트는 주로 마우스 및 입력양식에서 발생하며, 문서의 로딩과 관련된 특별한 이벤트를 포함한다.

대표적인 HTML Event는 다음과 같다. 더 많은 HTML Event는 여기에!

이벤트명설명
click클릭시 발생
change변동이 있을시 발생
focus포커스를 얻었을때 발생
keydown키를 눌렀을때 발생
keyup키에서 손을 땠을때 발생
load문서의 로드가 완료 되었을때 발생
unload문서가 언로드 되었을때 발생
resize윈도우 크기가 변경될 경우 발생
mouseover마우스가 특정 객체 위로 올려졌을 시에 발생
mousedown마우스를 클릭 했을때 발생
mouseout마우스가 특정 객체 밖으로 나갔을 때 발생
mousemove마우스가 움직였을 때 발생
mouseup마우스에서 손을 땟을때 발생
selectoption 태그 등에서 선택을 했을때 발생
submit입력양식이 제출 요청 될때 발생

✴︎ Event Handler

이벤트 핸들러는 이벤트 발생을 감지하고 처리할 코드를 수행하는 역할을 담당한다.

HTML 태그의 속성으로 지정하거나, JavaScript 파일에서 DOM Element의 속성에 콜백함수를 정의하는 형식으로 사용한다. 보편적으로 이벤트 핸들러는 이벤트 이름의 앞에 'on'을 붙여 사용한다.

① HTML 속성으로 정의

이벤트를 감지하기 위한 HTML 태그의 속성에 이벤트 핸들럴를 할당한다.

<input type="button" value="Button" onclick="alert('버튼 클릭됨!!')"></input>

② JavaScript에서 정의

자바스크립트 코드를 사용해 DOM Element(= 특정 HTML Tag)를 선택해 속성으로 이벤트 발생시 호출될 콜백 메서드를 정의한다.

document.getElementById('b1').onclick = function() {alert("버튼 클릭됨!!")}

또는 addEventHandler()를 이용해 이벤트 핸들러를 추가할 수 있다.

document.getElementById("id_name").addEventHandler("click", function(){ code });

02. DOM Event 흐름

표준 DOM Event에서 정의한 이벤트 흐름엔 3가지 단계가 있다.

① 캡처링 단계 : 이벤트가 하위 요소로 전파되는 단계
② 타깃 단계 : 이벤트가 실제 타깃 요소에 전달되는 단계
③ 버블링 단계 : 이벤트가 상위 요소로 전파되는 단계

아래 그림에서 <td /> 태그를 클릭하면 이벤트가 최상위 조상부터 시작해 아래로 전파되는 캡처링 단계 → 이벤트가 타깃 요소에 도착해 실행되는 타깃 단계 → 마지막으로 다시 위로 전파되는 버블링 단계를 거친다.

DOM Event는 3가지 단계를 통해 요소에 할당된 이벤트 핸들러가 호출된다.


✴︎ Event Bubbling (이벤트 버블링)

이벤트 버블링은 특정 화면 요소에서 이벤트가 발생했을 때, 해당 이벤트가 더 상위 요소들로 전달되어 가는 특성을 의미한다.

DOM은 기본적으로 트리 구조를 갖는다. 따라서 트리 구조에서 현재 요소보다 한 단계 위에 있는 요소를 상위요소라고 하며, body 태그가 최상위 요소가 된다.

⛔️ 거의 모든 이벤트는 버블링 된다.

여기서 중요한 포인트는 '거의' 이다.

focus 이벤트와 같이 버블링이 되지 않는 몇몇 이벤트를 제외하곤 대부분의 이벤트는 버블링 된다.


✋ 이벤트 버블링 중단하기 : event.stopPropagation()

원하는 요소에서만 이벤트를 발생하게 하고 싶다면, event.stopPropagation()를 통해 버블링을 중단할 수 있다. 이를 통해 클릭한 타깃만 이벤트가 발생하고, 상위 요소로 이벤트가 전파되는 것을 막아준다.

<form onclick="alert('버블링은 여기까지 도달하지 못합니다")">FORM
  <div onclick="event.stopPropagation()">클릭해주세요.</div>
</form>

💡 한 요소의 이벤트 핸들러가 두개라면?

한 요소의 특정 이벤트를 처리하는 핸들러가 여러개라면, event.stopPropagation()를 통해 하나의 핸들러의 버블링을 멈추더라도 나머지 핸들러는 여전히 동작한다.

즉, event.stopPropagation() 는 상위로 일어나는 버블링은 막아주지만, 같은 요소에 할당된 다른 핸들러들이 동작하는 건 막지 못한다.

따라서 상위로 일어나는 버블링을 중단하고, 같은 요소에 할당된 다른 핸들러의 동작도 막으려면 event.stopImmediatePropagation()를 사용하면 된다. 이 메서드를 사용하면 해당 요소에 할당된 이벤트를 처리하는 모든 핸들러의 동작이 중단된다.

❓ 이벤트 버블링 중단, 올바른가?

버블링은 매우 유용하므로, 버블링을 꼭 멈춰야 하는 상황이 아니라면 버블링을 막지 않는 것이 좋다.
👉 event.stopPropagation()을 사용한 영역은 ‘죽은 영역(Dead Zone)’이 되어버리기 때문이다.

따라서 불가피하게 버블링을 막아야한다면, event.stopPropagation() 대신 커스텀 이벤트 등을 사용해 이벤트 버블링을 통제하는 것이 좋다.


✴︎ Event Capturing (이벤트 캡쳐링)

이에 반해 이벤트 캡쳐링은 최상위 요소부터 시작해 타깃 요소까지 아래로 전파되는 과정을 의미한다.


02. Event Target

이벤트가 발생한 가장 안쪽 요소는 타깃(target) 요소라고 불리고, event.target을 통해 타깃 요소에 접근 할 수 있다.

부모 요소의 핸들러는 이 타깃요소를 통해 이벤트가 정확히 어디서 발생했는지 등에 대한 자세한 정보를 얻을 수 있다.

✴︎ target vs CurrentTarget

console.log(event)를 찍어보면 targetcurrentTarget이 있는 것을 알 수 있다.

비슷한 의미 같은데, 이 둘은 어떻게 다를까? event객체에 속해있는 targetcurrentTarget의 차이점에 대해 알아보자.

결론부터 말하면,

target은 실제 이벤트가 발생하는 요소이고,

currentTarget은 이벤트 리스너가 달린 요소이다.

• VanillaJS

<!--HTML-->
...
  <body>
    <ul>
       <li>
      	<button id="oauth">
        	<span>Google</span>
    	</button>
       <li>
    </ul>
  </body>
  <script>
    const googleOauthElement = document.querySelector('#oauth');
    googleOauthElement.addEventListener('click', (e) => {
      console.log(e.target);
      console.log(e.currentTarget);
    })
  </script>
...

• JSX

const onLogin = (e) => {
  console.log(e.target);
  console.log(e.currentTarget);
}

function APP() => {
  ...
    <li>
      	<button onClick={onLogin}>
        	<span>Google</span>
    	</button>
    <li>
  ...
}

👀 결과

그럼 다음과 같이 event.target은 자식 요소인 span을 리턴하고, event.currentTarget은 부모 요소인 button을 반환하는 것을 알 수 있다.

target은 실제 이벤트가 발생하는 요소이고,

currentTarget은 이벤트 리스너가 달린 요소이다.


💡 읽어볼 Article



※ 참고자료

profile
한입 크기로 베어먹는 개발지식 🍰

0개의 댓글

관련 채용 정보