Search
Duplicate

EVENT

Event를 알아야 하는 이유

input창에 값을 입력하고, 엔터를 쳤을 때 지하철역을 리스트에 추가하고 싶다면?
삭제 버튼을 눌렀을 때 지하철 역을 삭제하고 싶다면?
인터렉티브한 사용자 경험을 만들고 싶다면?
위와 같은 이벤트를 유연하게 처리하기 위해서 우리는 반드시 이벤트를 알아야 합니다.
동적인 웹은 사용자와 상호작용이 잘 되야 합니다. 그리고 그 상호작용은 어떤 이벤트에 의해 발생합니다.
그래서 프론트엔드에서 많은 인터렉션은 모두 Event 를 처리하는 것과 깊은 관련이 있습니다.

목표

이벤트 종류를 최소 3가지 이상 말할 수 있다.
DOM Element에 이벤트를 바인딩 할 수 있다.
이벤트의 흐름을 제어할 수 있다.
이벤트 위임을 사용할 수 있다.

Event

우리는 웹페이지 내에서 많은 동작들을 취하고 이 모든 동작은 이벤트(Event)가 됩니다.
예를 들어 로그인 아이디를 '입력했을 때', 로그인 버튼을 '클릭 했을 때', 설문조사 '체크박스에 체크했을 때' 비밀번호를 입력 후 '엔터를 쳤을 때' 등등 해당 동작에 대한 이벤트가 발생하고 다룰 수 있습니다.

Event의 종류

1. 사용자 인터페이스 이벤트

사용자 인터페이스(UI)이벤트는 브라우저가 로드한 HTML페이지가 아닌 브라우저 창을 사용할 때 발생하는 이벤트.(ex: 페이지 로드, 브라우저 크기 조절...)
Search
이벤트
설명
웹 페이지가 unload 될 때(새로운 페이지를 요청한 경우)
브라우저가 자바스크립트 오류를 만났거나 요청한 자원지 존재하지 않는 경우
브라우저 창의 크기를 조정했을 때
사용자가 페이지를 위아래로 스크롤 할 때
COUNT5

2. 키보드 이벤트

사용자가 키보드를 이용할 때 발생합니다.
Search
이벤트
설명
사용자가 키를 처음 눌렀을 때(키가 눌린 동안은 계속해서 발생)
사용자가 키를 뗄 때
사용자가 키를 눌렀다가 떼어서 문자가 화면에 나타나게 되면 발생 화살표 키를 누를 때 keydown 이벤트는 발생하지만 이 이벤트는 발생하지 않는다.
COUNT3

3. 마우스 이벤트

마우스를 움직이거나 버튼을 클릭할 때 발생합니다.
Search
이벤트
설명
마우스를 클릭했을 때
마우스를 더블 클릭했을 때
마우스를 누르고 있을 때
요소 위에서 누르고 있던 마우스를 뗄 때
마우스를 움직일 때(터치 스크린에서는 동작 X)
요소 위로 마우스를 움직였을 때(터치스크린 동작 X)
요소 바깥으로 마우스를 움직였을 때(터치스크린 동작 X)
COUNT7

4. focus와 blur 이벤트

사용자가 상호작용이 가능한 링크나 폼 요소 같은 HTML요소는 포커싱이 가능합니다.
이런 요소들은 자신이 포커싱이 되었거나 해제될 때 이벤트를 발생시킵니다.
Search
이벤트
설명
요소가 포커스를 얻었을 때
요소가 포커스를 잃었을 때
COUNT2

이벤트 핸들러

사용자가 웹 페이지의 HTML과 상호작용할 때 이벤트를 핸들링하도록 프로그래밍 할 수 있습니다.
이벤트 핸들링 하는 방법은 크게 3가지가 있습니다.
1.
HTML 이벤트 핸들러.
2.
전통적인 DOM 이벤트 핸들러
3.
이벤트 리스너(Event Listener)
보통 3번을 가장 많이 사용하기에 3번의 방법만 소개합니다.

활용

function eventHandler(){...} const $stationAddButton.addEventListener('click', eventHandler);
JavaScript
복사
click : 대기하고자하는 이벤트. 위 예제에서는 클릭 이벤트를 기다립니다.
eventHandler: 이벤트가 발생했을 때 실행될 코드. 예제에서는 eventHandler()함수를 호출합니다. 여기서 메서드 호출인데 괄호(()) 가 생략된 이유는 괄호를 포함시킬 경우 즉시실행 함수가되어 이벤트가 바인딩 되는 시점에서 함수가 호출되기 때문에 의도와 다르게 동작을 합니다.
익명함수(anonymouse function)를 호출하여 안에서 자체적으로 로직을 구현하는 것도 가능합니다. 이는 1회성의 재활용빈도가 낮은 함수를 사용하거나, 호출 할 함수에 인자값을 전달해야 하는 경우입니다.
const $stationAddButton.addEventListener('click', (event)=>{ console.log("click Element: ", event.target); }); function eventHandlerByParam(param){...} const $stationAddButton.addEventListener('click', (event)=>{ eventHandlerByParam(event.target); });
JavaScript
복사

이벤트의 흐름과 제어

대부분의 HTML요소는 다른 요소의 내부에 중첩됩니다. 그렇기에 버튼에 마우스를 가져가거나 클릭하면, 그 부모 요소 혹은 자식요소 또한 같이 클릭한 것과 같은 동작을 일으키게 됩니다.
<html> <body> <div> <ul> <li><a href="/example_one">one</a></li> </ul> </div> </body> </html>
HTML
복사
위와 같은 목록을 예로 들 때 링크를 클릭하면 자바스크립트는 요소에 이벤트를 발생시킴과 동시에 요소를 포함하고 있는 다른 모든 요소들에도 동일한 이벤트를 발생시킵니다. 이벤트가 발생하는 순서를 이벤트 흐름(event flow)이라고 하며, 이벤트가 흐르는 방식은 아래와 같이 두 가지가 있습니다.
이벤트 버블링: 이벤트가 사용자의 동작에 직접적으로 영향을 받은 노드로부터 바깥쪽으로 전파되어 나가는 방식.
이벤트 캡쳐링: 이벤트가 가장 바깥쪽의 노드로부터 시작해서 안쪽으로 전파되어 들어오는 방식
위와 같은 이벤트의 흐름으로 인해 내가 원하는 동작 외에 이벤트가 퍼져나가 예상 못한 오류가 발생할 수 있습니다.
이 때 객체가 제공해주는 메소드를 이용하면 문제를 미리 예방할 수 있습니다.

Event 객체

Event 객체는 이벤트가 발생했을 때 이벤트를 발생시킨 요소와 발생한 이벤트에 대한 정보를 제공합니다.
Event 객체가 제공하는 정보는 다음과 같습니다.
이벤트를 발생시킨 요소
keypress 이벤트가 어떤 키에 의해 발생했는지에 대한 정보
사용자가 어떤 요소를 클릭해서 click 이벤트가 발생했는지에 대한 정보
Search
속성
목적
이벤트가 발생한 요소(사용자가 의도한 가장 명확한 요소)
발생한 이벤트의 종류
COUNT2
Search
메서드
목적
링크 클릭 및 폼 제출과 같은 몇몇 이벤트 발생시 페이지 이동을 막는식의 이벤트의 기본 동작을 취소한다.
이벤트의 캡쳐링이나 버블링을 중단한다. 이벤트가 부모 요소로 버블링되는 것을(특히 부모 요소가 동일한 이벤트에 대해 개별적인 이벤트 핸들러를 가지고 있는 경우라면 더더욱) 중단하고 싶을 수 있다.
COUNT2

이벤트 위임

이벤트 리스너를 지정하는 요소가 많을수록 페이지의 실행속도는 느려집니다. 그래서 효율적으로 이벤트를 관리하기 위해서 이벤트의 흐름을 이용합니다.
이벤트는 이벤트가 발생한 엘리먼트를 포함하고 있는 부모 요소에도 영향을 미치기 때문에 자식 요소를 포함할 수 있는 요소에 이벤트 핸들러를 지정하고 이벤트의 흐름을 이용해 다룰 수 있습니다.
즉, 이벤트 리스너가 실행할 작업을 요소의 부모 요소에게 위임(Delegation)할 수 있다는 것입니다.

이벤트 위임의 장점들

동적으로 추가되는 요소들에도 동작한다.
DOM 트리에 새로운 요소를 추가하더라도 이벤트에 대한 처리는 부모 요소에게 위임되었기 때문에 새로운 요소에 이벤트 핸들러를 다시 지정할 필요가 없다.
간결한 코드
이 기법을 사용하면 함수를 많이 작성할 필요가 없으며 DOM과 코드간의 연결이 간소해져 결과적으로 유지보수에 도움이 된다.

예제

<ul id="parent-list"> <li id="item1">Item 1</li> <li id="item2">Item 2</li> <li id="item3">Item 3</li> </ul>
HTML
복사
//상위 노드에 이벤트 설정 document.getElementById("parent-list").addEventListener("click", function (e) { if (e.target && e.target.nodeName == "LI") { console.log(`List item ${e.target.id} was clicked!`); } });
JavaScript
복사