출처 : https://javascript.info/introduction-browser-events
'이벤트'란 무언가 발생했다는 신호이다.
Mouse events
- click
- contextmenu
- mouseover/mouseout
- mousedown/mouseup
- mousemove
Keyboard events
- keydown/keyup
Form element events
- submit
- focus
Document events
- DOMContentLoaded - DOM전체 생성 시
CSS events
- transitioned - CSS-animation 종료 시
Event handlers
event에 반응하기 위해, handler(event발생 시, 실행하는 함수)를 할당한다.
handler할당에 여러 방법이 있다.
HTML-attribute
on<event> attribute로 HTML에 세팅할 수 있다.
<input value="Click me" onclick="alert('Click!')" type="button">
마우스 클릭하면, onlick이 실행된다. onclick은 double quotes로 감싸져 있어서 내부 코드는 '(single quotes)만 사용한다. HTML-attribute는 많은 양의 코드를 작성하기 어려우므로, JavaScript함수를 작성하고 호출하는 것이 낫다.
DOM property
DOM property인 on<event>을 사용하여 handler를 할당할 수 있다.
HTML-attribute에 handler가 있는 경우, browser가 읽고 함수를 만들어 DOM property에 작성한다. 따라서 HTML-attribute와 DOM property는 사실 동일하게 동작한다.
<input type="button" id="button" value="Button">
<script>
button.onclick = function() {
alert('Click!');
};
</script>
onlick property는 오직 하나이다.
<input type="button" id="elem" onclick="alert('Before')" value="Click me">
<script>
elem.onclick = function() { // 기존의 handler를 overwrite한다.
alert('After'); // only this will be shown
};
</script>
handler를 삭제하기 위해서는 elem.onclick = null 처리한다.
Accessing the element: this
handler의 this는 handler가 할당된 element이다.
click시, 'Click me' text를 alert한다.
<button onclick="alert(this.innerHTML)">Click me</button>
Possible mistakes
events를 사용하면서 할 수 있는 실수들을 알아보자.
존재하는 함수를 handler로 설정할 수 있다.
function sayThanks() {
alert('Thanks!');
}
// right
button.onclick = sayThanks;
// wrong
button.onclick = sayThanks();
괄호를 추가하면, sayThanks()는 함수호출이된다. 따라서 마지막 줄은 함수실행의 결과를 받으며 undefined가 된다.
반면에 markup에서는 괄호가 필요하다.
<input type="button" id="button" onclick="sayThanks()">
차이점은 browser가 attribute를 읽을때 handler 함수를 생성한다.
button.onclick = function() {
sayThanks(); // <-- the attribute content goes here
};
handler 설정 시, setAttribute를 사용하지 않는다. 동작하지 않는다.
// a click on <body> will generate errors,
// because attributes are always strings, function becomes a string
document.body.setAttribute('onclick', function() { alert(1) });
DOM-property는 case-sensitive하므로 elem.onclick 으로 설정한다.
addEventListener
앞서 언급한 handler 설정방법의 문제는 하나의 event에 multiple handler를 설정할 수 없다는 점이다.
예를들어, 코드의 한 부분에서는 버튼 클릭시 highlight하고, 다른데서는 동일한 버튼 클릭시 메시지를 보여주려고 한다.
2개의 event handler를 설정하면, overwrite된다. addEventListener, removeEventListener 함수를 사용하여 handlers를 관리할 수 있다.
element.addEventListener(event, handler, [options]);
event : Event name
handler : handler function
options :
- once : true이면 trigger된 이후 listener는 자동으로 삭제된다.
- capture :
- passive : true이면 handler는 preventDefault()를 호출하지 않는다.
handler를 삭제하기 위해서 동일한 함수를 전달해야 한다.
//아래 소스는 동작하지 않는다. 동일한 코드지만, 다른 함수 객체이다.
elem.addEventListener( "click" , () => alert('Thanks!'));
// ....
elem.removeEventListener( "click", () => alert('Thanks!'));
아래가 올바른 방법이다. 함수를 변수로 저장하지 않으면 제거할 수 없다.
function handler() {
alert( 'Thanks!' );
}
input.addEventListener("click", handler);
// ....
input.removeEventListener("click", handler);
<input id="elem" type="button" value="Click me"/>
<script>
function handler1() {
alert('Thanks!');
};
function handler2() {
alert('Thanks again!');
}
elem.onclick = () => alert("Hello");
elem.addEventListener("click", handler1); // Thanks!
elem.addEventListener("click", handler2); // Thanks again!
</script>
Event object
event에 대해 자세히 알아보자.
event가 발생될 때, 브라우저는 event object를 생성하고 상세내용을 입력한 후, handler에 argument로 전달한다.
<input type="button" value="Click me" id="elem">
<script>
elem.onclick = function(event) {
// show event type, element and coordinates of the click
alert(event.type + " at " + event.currentTarget);
alert("Coordinates: " + event.clientX + ":" + event.clientY);
};
</script>
event.type : Event type, 여기서는 click 이다.
event.currentTarget : event를 handle하는 element이다. this와 동일하다.
event object는 HTML handler에도 유효하다.
<input type="button" onclick="alert(event.type)" value="Event type">
browser가 attribute를 읽으면 function(event){alert(event.type)}과 같은 함수를 생성한다.
Object handlers: handleEvent
addEventListener를 사용하여 event handler에 함수가 아닌 object도 할당이 가능하다. event발생 시, 그것의 handleEvent 함수가 호출된다.
<button id="elem">Click me</button>
<script>
let obj = {
handleEvent(event) {
alert(event.type + " at " + event.currentTarget);
}
};
elem.addEventListener('click', obj);
</script>
addEventListener가 handler로 object를 전달 받았을 때, obj.handleEvent(event)가 호출된다.
custom class를 사용할 수도 있다.
<button id="elem">Click me</button>
<script>
class Menu {
handleEvent(event) {
switch(event.type) {
case 'mousedown':
elem.innerHTML = "Mouse button pressed";
break;
case 'mouseup':
elem.innerHTML += "...and released.";
break;
}
}
}
let menu = new Menu();
elem.addEventListener('mousedown', menu);
elem.addEventListener('mouseup', menu);
</script>
두 이벤트를 동일한 object가 handle한다. handleEvent 함수가 모든 소스를 가질 필요 없다. 아래와 같이 event-specific함수를 호출하도록 수정할 수 있다.
<button id="elem">Click me</button>
<script>
class Menu {
handleEvent(event) {
// mousedown -> onMousedown
let method = 'on' + event.type[0].toUpperCase() + event.type.slice(1);
this[method](event);
}
onMousedown() {
elem.innerHTML = "Mouse button pressed";
}
onMouseup() {
elem.innerHTML += "...and released.";
}
}
let menu = new Menu();
elem.addEventListener('mousedown', menu);
elem.addEventListener('mouseup', menu);
</script>
event handler가 깔끔하게 나뉘어졌다.
Summary
event handler를 설정하는 3가지 방법이 있다.
- HTML attribute : onclick="...", 최소한으로 사용하는 방법!
- DOM property : elem.onclick = function.
- Methods: addEventListener, removeEventListener, 가장 flexible하다.
'JavaScript' 카테고리의 다른 글
Web APIs - Console API (0) | 2022.12.05 |
---|---|
JavaScript] Event Bubbling and capturing (0) | 2022.11.23 |
JavaScript] Coordinates (element 좌표) (0) | 2022.11.17 |
JavaScript] Window sizes and scrolling (0) | 2022.11.14 |
JavaScript] Document Styles and classes (1) | 2022.11.14 |
댓글