(ES5) - 11. 이벤트 핸들링

  • SUNGMIN SHIN
  • 20 Minutes
  • 2017년 9월 14일


[ 열혈강의 No More Copy & Paste 자바스크립트 ]

(http://book.naver.com/bookdb/book_detail.nhn?bid=6983102)


11. 이벤트 핸들링


서론


이벤트(EVENT)라는 객체는 웹 어플리케이션에 변화가 생길 때 생성됩니다.
어플리케이션이 처음 열리는 순간이나 마우스로 클릭하거나 키보드로 입력하는 등 특정 엘리먼트의 변화와 문서를 떠나는 순간까지의 모든 활동에 대해서 이벤트가 발생 합니다.

이러한 활동이 감지되면 자바스크립트는 스스로 이벤트 객체를 생성하고 이 객체는 해당 활동에 대한 여러가지 정보를 함께 갖고 있습니다.

특정한 이벤트에 대한 응답을 설정하거나 해제하는 행위를 이벤트 핸들링(event handling)이라고 말하고 이에 대한 응답으로 반응하는 함수를 리스너(listener)라고 합니다.

이벤트 핸들러들(Event handlers)은 DOM에 존재하는 다양한 엘리먼트들과 관련되어 있습니다. 이벤트가 발생하게 되면, 이벤트 객체는 동적으로 생성되며, 이벤트를 처리할 수 있는 이벤트 리스너(event listener)들로 전달됩니다. DOM의 Event 인터페이스는 핸들러 함수로 접근할 수 있으며, 이벤트 객체는 첫 번째 인자로만 전달됩니다.


11.1 기본 이벤트


이벤트 객체의 속성

속성 설명
bubbles 이벤트 작동 방식이 버블링인지 여부를 반환한다.
cancelable 이벤트가 취소되었는지를 반환한다.
currentTarget 이벤트 응답자가 수행되고 있는 대상 객체를 반환한다.
defaultPrevent event.preventDefault() 메서드를 사용하여 이벤트의 기본 행동을 취소할 수 있는 지 여부를 나타내는 boolean 값
eventPhase 이벤트 흐름에서 현재 단계를 알려주는 속성
eventPhase=1 일때 capture(EventPhase.CAPTURING_PHASE)
eventPhase=2 일때 target(EventPhase.AT_TARGET)
eventPhase=3일 때 bubbling(EventPhase.BUBBLING_PHASE)
explicitOriginalTarget 마지막으로 이벤트가 발생한 객체를 반환
originalTarget 이벤트가 최초로 발생한 객체를 반환한다.
target 이벤트가 실제로 발생한 객체(이벤트 응답자가 등록되지 않았더라도)를 반환한다.
timeStamp 이벤트가 발생한 시간을 반환.
type 발생한 이벤트의 형식을 반환한다.
isTrusted 이벤트 브라우저(EX> 사용자 클릭 이후) 또는 스크립트(event.initEvent 같은 생성 방법을 사용한 스크립트)에 의해 시작되었는지를 반환

이벤트 객체의 메서드

메서드 설명
initEvent() 새 이벤트 속성을 초기화한다.
preventDefault() 이벤트를 취소할 수 있다면 이벤트의 전파를 막지 않고 그 이벤트를 취소한다.
stopImmediatePropagation() 이벤트의 전파를 막고 현재 실행 중인 리스너 함수까지 실행한다.
stopPropagation() 이벤트의 전파를 막고 현재 엘리먼트에 등록된 응답자 함수까지 실행한다.


이벤트 전파

이벤트 전파란 특정 위치에 엘리먼트가 여러개 겹쳐 있는 지점에 click과 같은 이벤트가 발생 되었을 때 가장 위에 있는 엘리먼트에서만 click이벤트가 발생하는 것이 아닌 겹쳐져있는 아래 쪽 엘리먼트들에도 이벤트가 전달되는 것을 말 합니다.

예제 11-1(html)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<style>
div{margin:5px;padding:5px;border:1px solid black}
#depth1{background:darkgreen}
#depth2{background:yellowgreen}
#depth3{background:lightgreen}
textarea{width:90%;height:200px}
</style>

<div id="depth1">
depth1
<div id="depth2">
depth2
<div id="depth3">
depth3
</div>
</div>
</div>
<textarea name="" id="" cols="30" rows="10" style="width:100%;height:100px;"></textarea>

예제 11-1(javascript)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
window.onload = function(e) {
var logger = document.getElementsByTagName('textarea')[0];

function log(newtext) {
logger.value+= newtext + '\n';
logger.scrollTop = logger.scrollHeight;
}

var divs = document.getElementsByTagName('div');

for (var i = 0; i < divs.length; i++) {
(function(){
var div = divs[i];
div.onclick = function(e) {
if (div.id === 'depth1') {
log(div.id);
} else if (div.id === 'depth2') {
log(div.id);
} else if (div.id === 'depth3') {
log(div.id);
}
}
})();
}
};

위 예제는 div 엘리먼트 3개를 겹치게 하여 놓고 div 엘리먼트들에 클릭 이벤트가 발생하면 어떤 엘리먼트에서 이벤트가 발생했는지에 대한 로그를 textarea 엘리먼트에 보여주도록 되어 있습니다.
depth3을 클릭하면 depth3에서 이벤트가 전파되어 depth1까지 클릭 이벤트가 발생한 것을 확인할 수 있습니다.

참고> 이벤트 전파를 중단하는 네가지 방법

(http://programmingsummaries.tistory.com/313)



이벤트 속성에 대한 예제로 클릭과 클릭 사이의 시간 간격을 계산하는 어플리케이션 입니다.

예제 11-2 (html)

1
2
3
4
5
6
<h1>이벤트 핸들링</h1>
<div>
클릭한 간격:
<span id="msContent">0</span>
<button type="button">클릭</button>
</div>

예제 11-2 (javascript)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var eventCtrl = {
add: function(elem, eventType, handler) {
// 이벤트 타입에서 'on' 문자열 제거
eventType = eventType.replace('on', '');
// addEventListener 메서드가 존재한다면 실행
if (elem.addEventListener) {
elem.addEventListener(eventType, handler, false);
}else if(elem.attachEvent) {
eventType = 'on' + eventType;
elem.attachEvent(eventType, handler);
}
},
remove: function(elem, eventType, handler) {
eventType = eventType.replace('on', '');
if (elem.removeEventListener) {
elem.removeEventListener(eventType, handler, false);
}else if(elem.detachEvent) {
eventType = 'on' + eventType;
elem.detachEvent(eventType, handler);
}
}
};

eventCtrl.add(window, 'load', function(event){
var time = 0;
var button = document.getElementsByTagName('button')[0];

eventCtrl.add(button, 'click', function(event) {
var stamp = parseInt(event.timeStamp);
if (time > 0) {
document.getElementById('msContent').innerHTML = stamp - time;
}
time = stamp;
});
});

특정 엘리먼트에 이벤트를 등록하는 등의 어떠한 조작을 하려면 본문의 HTML 태그들이 완성된 후여야 합니다. 그러므로 페이지를 모두 읽은 다음에 버튼 엘리먼트에 이벤트를 등록하게 한 예제 입니다.


11.2 마우스 이벤트


마우스를 통해 발생된 이벤트를 일걷는 것으로 클릭하거나 대상 위로 마우스를 올리거나 혹은 드래그 앤 드롭과 같은 이벤트들이 여기에 속하게 됩니다 마우스를 통해 발생한 이벤트에는 마우스 위치, 버튼 정보들과 같은 다양한 정보를 포함하고 있습니다.
마우스 위치와 관련된 속성들은 아래와 같습니다.

속성 설명
clientX, clientY 브라우저 창을 기준으로 한 X, Y의 좌표 값(스크롤은 무시)
pageX, pageY 랜더링된 문서를 기준으로 한 X, Y 좌표, IE에서는 지원하지 않음
layerX, layerY,
offsetX, offsetY
타겟 엘리먼트를 기준으로 한 X, Y 좌표

이 정보들을 활용해 고전적인 방법의 그림을 그리는 웹 어플리케이션의 예제


11.3 키보드 이벤트


키보드 이벤트는 키보드를 통해 생성된 이벤트로 눌려진 버튼의 정보를 갖고 있습니다. 이때 이벤트가 발생하 키보드의 값은 event.keyCode 또는 event.which 속성으로 확인할 수 있고 이 값은 숫자로 나타나게 됩니다.


11.4 이벤트 목록


앞 서 다룬 것 외에도 이벤트 종류는 아주 많습니다. 모두 외울 필요는 없지만 어떤 종류의 이벤트가 있는지 한 번이라도 확인하고 지나가길 바랍니다.