우리가 무언가를 클릭하거나, 현재 보고있는 창을 새로고침할 때, 창을 닫을 때 등등

브라우저에서 일어나는 동작에 대해서 Event가 발생한다.

 

즉 브라우저는 Event 기반으로 동작한다고 할 수 있다.

 

이러한 다양한 종류의 Event에 대해서 알아보자

 

https://www.edwith.org/boostcourse-web/lecture/16700/

 

[LECTURE] 3) Browser Event, Event object, Event handler : edwith

들어가기 전에 어떤 영역을 마우스 클릭하거나, 화면을 스크롤 하거나 하는 작업에 따라서 브라우저는 반응합니다. 이런 것들은 모두 브라우저가 Event기반으로 동작되게 만들어졌기 때... - 부스트코스

www.edwith.org


Event객체

브라우저에서 발생하는 모든 동작에 대해서 이벤트가 발생한다.

  • 클릭
  • 브라우저의 화면의 크기를 마우스로 조정
  • 마우스 휠로 스크롤
  • 마우스로 어떤 것을 이동

모든 DOM 노드는 이런 신호를 만들어 낸다. 하지만 이벤트는 DOM에만 한정되진 않는다.

 

https://ko.javascript.info/introduction-browser-events

 

브라우저 이벤트 소개

 

ko.javascript.info

 

자주 사용되는 이벤트는 다음과 같다.

 

마우스 이벤트

  • click : 요소 위에서 마우스 왼쪽 버튼을 눌렀을 때
  • contextmenu : 요소 위에서 마우스 오른쪽 버튼을 눌렀을 때
  • mouseover, mouseout : 마우스 커서를 요소 위로 움직였을 때, 커서가 요소 밖으로 움직였을 때
  • mousedown, mouseup : 요소 위에서 마우스 왼쪽 버튼을 누르고 있을 때, 마우스 버튼을 뗄 때
  • mousemove : 마우스를 움직일 때

폼 요소 이벤트:

  • submit : 사용자가 <form>을 제출할 때
  • focus : 사용자가 <input>과 같은 요소에 포커스 할 때

키보드 이벤트

  • keydown과 keyup : 사용자가 키보드 버튼을 누르거나 뗄 때

문서 이벤트

  • DOMContentLoaded : HTML이 전부 로드 및 처리되어 DOM 생성이 완료되었을 때

CSS 이벤트

  • transitionend : CSS 애니메이션이 종료되었을 때

이 중에서 마우스와 키보드 이벤트를 살펴보면

"버튼을 누를 때" 와 "버튼을 뗄 때" 두 가지 이벤트가 존재한다.

 

이는 단순히 이벤트를 binding할 때 간과할 수 있는 부분인데, 예를 들어 키 입력에 대해 이벤트를 바인딩 한다고 가정해보자.

 

keydown으로만 이벤트를 바인딩 했을 때 다음과 같은 경우를 생각해 볼 수 있다.

  1. 'A'키를 누른 상태에서 때지 않고
  2. 'B'키를 입력하는 경우

즉 이벤트의 순서가 꼭 down > up > down > up 의 순서가 아닐수도 있는 것이다.

Event listener

브라우저는 Event를 발생시켜준다. 개발자는 그때 할 동작을 등록할 수 있다.

다시 말해, HTML엘리먼트별로 어떤 이벤트(주로 키보드나 마우스 관련)가 발생했을 때 특정 행위를(어떤 일) 하고 싶다면, 대상엘리먼트를 찾고 어떤 일을 등록하면 된다.

 

간단한 코드부터 살펴보자

var target = document.querySelector(".target");

target.addEventListener("click", function(e){
  console.log(e);
}, false);

https://developer.mozilla.org/ko/docs/Web/API/EventTarget/addEventListener

 

EventTarget.addEventListener()

EventTarget의 addEventListener() 메서드는 지정한 이벤트가 대상에 전달될 때마다 호출할 함수를 설정합니다.

developer.mozilla.org

위 코드에서 false 부분은 option이다. option의 의미는 MDN 문서를 통해 알아볼 수 있다.

 

예제에 사용한 false 는 capture속성이다.

 

capture : DOM 트리의 하단에 있는 EventTarget 으로 전송하기 전에, 등록된 listener 로 이 타입의 이벤트의 전송여부를 나타내는 Boolean 입니다.

 

그렇다면 다음 코드에 인자로들어가는 함수 function의 인자 e는 무엇일까?

 

이벤트 객체

 

위 코드를 실행시키기 위해 다음과 같은 html 파일을 제작하자

 

<html>
<body>
  <div id="target">aa</div>
</body>

<script>
  var el = document.getElementById("target");
  
  el.addEventListener("click", function(event){
   console.log(event);
  }, false);
</script>
</html>

콘솔에는 다음과 같이 출려된다.

MouseEvent {isTrusted: true, screenX: 1008, screenY: 153, clientX: 16, clientY: 19, …}

 

이 중에서 가장 많이 사용하는것은 Event 객체의 target, currentTarget property이다.

Event.target은 이벤트가 발생한 element를 나타낸다.

 

그렇다면 currentTarget은 무엇일까?

Event.currentTarget의 경우 이벤트가 바인딩된 요소, 해당하는 요소를 반환한다.

 

아래의 예제를 살펴보자

<div onclick="checkTarget();">
  <span>test</span>
</div>

<script>
function checkTarget(event) {
  var el = event.currentTarget;
  console.log(el);
}
</script>

만약 사용자가 div 내부의 span 태그를 클릭한 경우 각각은 다음과 같다.

 

Event.target : 클릭된 span 태그

Event.currentTarget : 이벤트가 바인딩된 div 요소를 반환

 

만약 이벤트를 binding한 곳과 클릭한 곳의 depth가 깊어지는 경우 Event.target 만으로는 어떤 요소가 클릭되어 반환되어야하는지 알기 쉽지 않다.

이 경우 currentTarget을 이용해 이벤트가 바인딩 된 곳을 알 수 있다.

이벤트 버블링 (전파)

다음과 같은 구조를 생각해보자

 

Wijmo HTML Events Capturing and Bubbling

Element 1, Element 2, Element 3모두에 이벤트 리스너를 등록한 상태에서, Element 3 를 클릭한 경우에는 어떻게 될까?

Element 3는 Element 2에 속하고, Element 2는 Element 1 에 속하기 때문에 3개의 이벤트가 발생한다.

 

이것을 이벤트 전파라고 한다.

 

이벤트 전파는 버블링과 캡처링 방식 두 가지 방식으로 동작한다.

클릭한 지점이 하위엘리먼트 이더라도, 그것을 감싸고 있는 상위 엘리먼트까지 올라가면서 이벤트리스너가 있는지 찾는 과정이다. 

 

다음의 경우를 생각해 보자

<ul>
  <li>
    <div>
    	<!-- something 1 -->
    </div>
  </li>
  <li>
    <div>
    	<!-- something 2 -->
    </div>
  </li>
  <li>
    <div>
    	<!-- something 3 -->
    </div>
  </li>
</ul>

위와 같은 구조에서 각 li 태그마다 이벤트 리스너를 직접 할당해 줄 수 있다.

그러나 이 경우 브라우저는 li 태그의 갯수만큼 이벤트 리스너를 기억하고 있어야 한다.

 

이 경우 다음과 같은 방법으로 최적화 할 수 있다.

  1. 최 상위 태그에 이벤트리스너를 등록하고
  2. Event.target을 이용해 분기처리 (각각의 li태그를 의미하기 때문에)

단순히 정적인 웹을 표기하고자 한다면 이벤트는 필요 없다. 그러나 동적인 웹을 제작하기 위해선 이벤트는 필수적이다.

 

그러나 브라우저가 너무 많은 이벤트핸들러를 기억하고 있는 것은 자원의 낭비일수도 있다.

 

따라서 브라우저가 너무 많은 이벤트핸들러를 기억하지 않게 하고, DOM이 추가되거나 삭제 될때 Event등록을 매번 해주지 않도록 최적화 하는 과정이 필요하다.

 

 

+ Recent posts