본문 바로가기

Front-End: Web/JavaScript

이벤트의 모든 것: on, addListener, onclick, addEventListener

반응형

노드 교과서 4장에서 addEventListener 메서드를 사용하여 클릭 이벤트를 작성하던 중,

예전에 클릭 이벤트 코드를 작성할 때 onclick 혹은 .on('click', listener) 메서드를 사용했던 기억이 떠올랐다.

그러다 이 이벤트들 사이에 어떤 차이가 있는지 궁금해졌고 조사하던 중

항상 헷갈렸던 용어들도 공부하며 이벤트의 모든 것을 정리하기로 했다.

 

1. 용어 정리

1.1 이벤트

웹 페이지에서 마우스를 움직이거나, 요소를 클릭하거나, 텍스트 박스에 글쓰기 등 특정 동작을 수행하는 것을 이벤트가 발생했다고 한다. 

그리고 이벤트가 발생할 때마다 웹 브라우저가 서버에게 그 사실을 알려준다.

 

1.2 이벤트 처리기

1.2.1 이벤트 처리기란?

이벤트가 발생했을 때 이에 반응하여 수행할 동작이 작성된 함수에 연결되도록 하는 처리기.

즉, 해당 이벤트가 발생할 때 대응하여 동작하는 콜백함수를 말한다.

 

1.2.2 이벤트 처리기의 구분

▪ 이벤트 핸들러

     하나의 요소에 하나의 이벤트만 처리하도록 설정할 수 있다.

 이벤트 리스너

     하나의 요소에 여러 이벤트를 처리하도록 설정할 수 있다.

 

➡ onclick 메서드는  마우스를 클릭하는 이벤트만 처리할 수 있다. 하나의 이벤트만 처리할 수 있으므로 이는 이벤트 핸들러이다.

하지만 addEventListener 메서드는 하나의 요소에 여러 이벤트를 가질 수 있다. 따라서 이벤트 리스너이다.

아래 예제를 보면 이해가 될 것이다.

const btn = document.getElementById('btn');

btn.onclick = () => { ... }

btn.addEventListener('click', () => { ... });
btn.addEventListener('hover', () => { ... });
btn.addEventListener('mouserdown', () => { ... });
이벤트 메서드명 onclick addEventListener
이벤트 처리기 구분 이벤트 핸들러 이벤트 리스너

onclick 메서드와 addEventListener에 대해선 아래에서 자세히 배운다. 지금은 이벤트 핸들러와 이벤트 리스너의 차이를 알고 넘어가자.

 

이벤트 핸들러의 모든 종류를 알고 싶다면 아래 링크를 참고하자. 모두 외울 필요는 없고, 필요에 따라 검색하여 사용하면 된다.

 

[JavaScript] 이벤트 핸들러 종류

JAVASCRIPT 이벤트 핸들러 정리입니다. onabort 이미지의 다운로드를 중지할 때 (브라우저의 중지버튼) onactivate 개체가 활성활 될 때 발생(태그의 기능이 작용할 때 발생하는 이벤트로 예를 들어 링크

ggoreb.tistory.com

 

13.2 이벤트 - 이벤트 객체

event 객체 DOM과 관련된 이벤트가 발생하면 관련 정보는 모두 event객체에 저장됩니다. 이벤트 발생 요소, 이벤트 타입, 이벤트 관련 데이터도 저장됩니다. ex) 마우스 이벤트 -> 마우스의 위치정보

blog.sonim1.com

 

1.2.3 이벤트 객체

이벤트 처리기는 이벤트 객체를 인수로 전달받을 수 있다. 전달되는 인수는 event 객체 단 하나 뿐이다.

이렇게 전달받은 이벤트 객체를 이용하여 이벤트의 성질을 결정하거나, 이벤트의 기본 동작을 막을 수도 있다.

 

이벤트 객체의 프로퍼티 및 메서드

프로퍼티/메서드 타입 R/W 설명
bubbles bool R 이벤트가 버블링되는지 나타냄
cancelable bool R 이벤트의 기본 동작 취소가능 여부
currentTarget element R 현재 이벤트를 처리 중인 element (=이벤트 핸들러 내부의 this와 동일)
defaultPrevented bool R true면 preventDefault() 호출 상태임
detail integer R 이벤트와 관련된 추가 정보
eventPhase integer R 이벤트 핸들러가 호출된 단계(1:캡처링, 2:타깃, 3:버블링)
preventDefault() Function R 이벤트의 기본행동 취소. cancelable이 true일 때만 가능함
stopImmediatePropagation() Function R 이벤트 캡처링, 이벤트 버블링 모두 취소하며 다른 이벤트 핸들러 호출을 막음
stopPropagation() Function R 이벤트 캡처링, 이벤트 버블링 모두 취소함. bubbles가 true일 때 가능함
target element R 이벤트 타깃
trusted bool R 브라우저에서 생성한 이벤트라면 true,
개발자가 만든 자바스크립트 이벤트라면 false
type string R 발생한 이벤트 타입
view AbstractView R 이벤트와 연결된 추상화된 뷰.
이벤트가 발생한 window객체와 일치함

➡ 이벤트 핸들러 내부의 this는 항상 currentTarget와 값이 일치하다. target에는 이벤트의 실제 타깃만 포함된다. (예제 2 참고)

 

예제 1 : 이벤트 객체

const btn = document.getElementById('btn');

btn.onclick = (event) => {
    console.log(event.type); // click
}

btn.addEventListener('click', (event) => {
    console.log(event.type); // click
}

 

예제 2 : 이벤트 객체의 메서드 currentTarget, target

<body>
    <input type="button" id="mybtn" value="click me"/>
</body>
document.body.onclick = (event) => {
    console.log(event.currentTarget === document.body); // true
    console.log(this === document.body); // true
    console.log(event.target === document.getElementById('mybtn')); // true
}

body에 클릭 이벤트를 추가하였다. 그래서 currentTarget과 this는 body 요소를 가리킨다.

하지만 target은 현재 클릭된 실제 타켓 요소를 가리킨다.

이벤트를 body에 할당한 것이지 버튼에 할당한 게 아니므로 이벤트를 찾아 document까지 거슬러 올라간다.

 

예제 3 : 여러 이벤트 핸들러 처리하기

const btn = document.getElementById('mybtn');
const handler = (event) => {
    switch(event.type) {
        case "click":
            // 코드
            break;
        case "mouseover":
            // 코드
            event.target.style.backgroundColor = 'red';
            break;
        case "mouseout":
            // 코드
            event.target.style.backgroundColor = '';
            break;
    }
};

btn.onclick = handler;
btn.onmouseover = handler;
btn.onmouseout = handler; 

이벤트 객체의 메서드 event.type을 이용하여 handler 함수 하나에서 세 가지 이벤트를 처리하도록 하는 코드이다.

 

 

2. 이벤트 처리기 등록

자바스크립트에서 이벤트 처리기를 등록한다는 것은 웹 페이지의 '요소'와 '이벤트 처리기'를 연결한다는 의미이다.

주로 DOM(Document Object Model)에 의존하여 HTML의 요소를 가져오며, 이벤트 처리기를 등록하는 방법은 다음과 같다.

이벤트 처리기 등록하는 방법

 

2.1 HTML 요소의 속성으로 등록하기

태그에 직접 지정하는 방식이다.

HTML 요소의 속성 중 'on+이벤트타입' 속성이벤트 호출 함수를 연결한다.

아래의 예제 경우에는 HTML 요소의 onclick 속성에 이벤트 핸들러를 연결하였다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script>
        function myFunction() {
            // 코드 작성
        }
    </script>
<body>
    <button onclick = "myFunction()">Click Me</button>
</body>
</html>

 

2.2 DOM 요소의 프로퍼티에 등록하기

script 태그 안에서 지정하는 방식이다.

DOM(Document Object Model)은 자바스크립트와 같은 프로그램이 HTML 요소를 조작할 수 있도록 제공되는 인터페이스다. DOM에는 여러 가지 객체가 있는데, 그 중에서 가장 대표적인 객체는 document와 window이다.

아래는 DOM의 window 객체와 document 객체를 이용하여 이벤트 핸들러를 등록한 예제이다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script>
        function myFunction() => {
            // 코드 작성
        }
        window.onload = () => {
            const btn = document.getElementById('btn');
            btn.onclick = myFunction;
    </script>
<body>
    <button id="btn">Click Me</button>
</body>
</html>

window.onload 프로퍼티는 웹 브라우저가 HTML 문서를 모두 읽어들였을 때 호출될 함수를 저장하는 프로퍼티이다.

HTML 문서를 모두 읽었을 때 document 객체를 통해 id가 'btn'인 요소를 불러오고 btn 변수에 저장한다. 그리고 onclick 프로퍼티에 이벤트 처리 함수인 myFunction()을 등록한다.

이벤트 핸들러에 함수명을 지정하거나, 직접 함수를 작성해도 된다.

1) 함수명 지정하기

element.onclick = myFunction;

function myFunction() {
    // 코드
}

2) 직접 함수 작성하기

element.onclick = () => {
    // 코드
}

 

2.3 addEventListener 메서드를 사용하는 방법 (➡ 가장 표준적인 방법)

addEventListener 메서드를 이용하여 이벤트 리스너를 등록하는 방법이다.

 

특정 요소에 여러 이벤트 처리기를 등록할 수 있으며,

버블링과 캡처링 단계 모두에서 가능하고, 정밀하게 제어도 가능하다.

 

구문

target.addEventListener(type, listener, useCapture);
  • type : 이벤트 유형(ex. click, mouseup, dbclick, ... )
  • listener : 이벤트 처리 내역
  • useCapture : true면 캡처링 단계, false면 버블링 단계(기본값)

 

예제 : 여러 이벤트 처리기 등록하기

function myFunction1() { ... }
function myFunction2() { ... }

const btn = document.getElementById('btn');
btn.addEventListener('click', () => myFunction1; };
btn.addEventListener('click', () => myFunction2; };

등록된 두 개의 이벤트 처리기가 순차적(myFunction1 ➡ myFunction2)으로 실행이 된다.

 

 

 

 

 

2.4 jQuery의 이벤트 핸들러를 사용하는 방법

jQuery를 사용할 때 이벤트 처리는 아주 빈번하게 사용하는 기능 중 하나이다.

 

 

 

 

 

 

 

 

 

 

3. 이벤트 처리기 삭제

3.1 이벤트 핸들러 삭제

on이벤트명 속성에 null 값을 설정한다.

target.onclick = null;

 

3.2 이벤트 리스너 삭제

removeEventListener 메서드를 사용한다.

target.removeEventListener(event, listener)

 

 

 

 

 

 

 

Node.js

  • on(event, listener)
  • addListener(event, listener)
  • 두 메서드는 아예 동일한 것임. 둘 중 익숙한 것을 사용하면 된다.

Javascript

  • onclick = listener
  • addEventListener(event, listener)

우선 알아야하는게, 노드에서 저 메서드들은 이벤트 모듈 > EventEmitter 클래스에 있는 메서드들을 사용하는거다.

하지만 이벤트는 자기가 만드는 것임. 원하는 이벤트명을 짓고 이벤트를 동작시켰을 때(emit) 동작할 내용을 작성하는 것.

 

그에 반해 자바스크립트는 HTML의 element만을 가져오고, 자바스크립트에서 지정한 이벤트만을 적용할 수 있다.

HTML DOM Events List

 

HTML DOM Event Object

HTML DOM Events HTML DOM Events HTML DOM events allow JavaScript to register different event handlers on elements in an HTML document. Events are normally used in combination with functions, and the function will not be executed before the event occurs (su

www.w3schools.com

그러니까 걍 사용 목적과 특성 자체가 다른 것임.. 

글쓰는 목적은 이벤트가 헷갈려서 뭐가 다른지 정리하려고 하는 거였는데,

javascript에서 이벤트랑 node.js에서 이벤트의 의미가 다른거였다.

 

아 그리고 맨 처음에 떠올라서 헷갈려했던 on('click', listener)는

$(element).on('click', listener);

이거다. 노드에서 on이 아니고 자바스크립트에서 on임

 

Node.js

노드에서는 이벤트 모듈과 EventEmitter 클래스가 내장되어 있다.

require() 메서드를 사용하여 이벤트 모듈을 로드하고, 이벤트를 활용할 객체를 EventEmitter 클래스로 로드하여 사용한다.

var EventEmitter = require('events');
var custom_event = new EventEmitter();

// 이벤트 생성
custom_event.on('call', () => {
    console.log('event call');
});

// 이벤트 발생
custom_event.emit('call');

// 이벤트 제거
custom_event.removeListener('call');

// 모든 이벤트 제거
custom_event.removeAllListener();

 

events 객체의 메서드

  • on(event, listener) : node.js의 Event 모듈
  • once(event, listener) : 이벤트를 한 번만 연결한 후 제거한다.
  • addListener(event, listener) : on() 메서드와 같다. 이벤트를 생성하는 메서드이다.
  • removeListener(event, listener) : 특정 이벤트의 특정 이벤트 핸들러를 제거한다. 이 메서드를 이용해 리스너를 삭제하면 리스너 배열의 인덱스가 갱신되니 주의해야 한다.
  • removeAllListener([event]) : 모든 이벤트 핸들러를 제거한다.
  • emit(eventName[, args]) : 이벤트를 발생시킨다.
  • setMaxListeners(n) : 한 이벤트에 최대허용 개수를 n으로 정한다. default값은 10이고, n=0이면 개수 제한이 사라진다.

 

먼저 

 

 

 

 

1. 콜백함수 개수

onclick은 하나의 콜백함수만 지정할 수 있다. 따라서 여러 개의 이벤트 핸들러를 사용하게 되면 기존 이벤트 핸들러를 덮어쓰기 때문에 가장 아래에 추가한 핸들러만 제대로 작동한다.

하지만 addEventListener는 여러 개의 이벤트 리스너를 사용할 수 있다. 따라서 여러 이벤트 핸들러를 작성하여도 모든 핸들러가 정상적으로 작동한다.

예제

var btn = document.getElementById('btn');

btn.onclick = () => { alert('onclick-1'); }
btn.onclick = () => { alert('onclick-2'); }

btn.addEventListener('click', () => { alert('addEventListener-1'); });
btn.addEventListener('click', () => { alert('addEventListener-2'); });

// onclick-2
// addEventListener-1
// addEventListener-2
const EventEmitter = require('events');
const myEmitter = new EventEmitter();

// First listener
myEmitter.on('event', function firstListener() {
  console.log('Helloooo! first listener');
});
// Second listener
myEmitter.on('event', function secondListener(arg1, arg2) {
  console.log(`event with parameters ${arg1}, ${arg2} in second listener`);
});
// Third listener
myEmitter.on('event', function thirdListener(...args) {
  const parameters = args.join(', ');
  console.log(`event with parameters ${parameters} in third listener`);
});

console.log(myEmitter.listeners('event'));

myEmitter.emit('event', 1, 2, 3, 4, 5);

// Prints:
// [
//   [Function: firstListener],
//   [Function: secondListener],
//   [Function: thirdListener]
// ]
// Helloooo! first listener
// event with parameters 1, 2 in second listener
// event with parameters 1, 2, 3, 4, 5 in third listener

 

 

2. 구형 브라우저 지원

onclick은 왜 있을까?

초기 DOM Level-0에서 제공된 기능이 onclick이고,

그 이후 DOM Level-2에서 추가된 기능이 addEventListener이다.

 

onclick보다 addEventListener가 더 유용하지만, addEventListener는 IE8 이하에서는 작동하지 않는다.

따라서 구형 브라우저 지원이 필요하다면 onclick을 사용하거나 다른 방법을 찾아야 한다.

 

3. 이벤트 중복

on은 이벤트가 중복되지만 addEventListener는 이벤트가 중복되지 않는다.

만약 클릭 click 이벤트가 무한 반복해서 들어온다면(같은 엘리먼트에 중복해서 클릭 이벤트를 발생시키면)

이벤트 대체가 아닌 중복이 되어 누적된 모든 이벤트를 다 실행시킨다는 것이다.

따라서 같은 element에 중복해서 클릭 이벤트를 발생시키면 그 수만큼 중복 실행된다.

 

이벤트 중복 발생 문제 해결

 

[JS/jQuery] click 이벤트 무한반복 / 중복 발생 처리

JS 개발 시 클릭 click 이벤트가 무한 반복해서 들어올 때... "클릭 이벤트를 재정의하면 (같은 엘리먼트에 중복해서 클릭 이벤트를 발생시키면) 이벤트 대체가 아닌 중복이 되어 누적된 모든 이벤

coding-restaurant.tistory.com

 

jQuery click 이벤트 중복 발생 문제 해결

click 이벤트 안에 console 찍고 있는데 console이 두 번씩 찍히는 것이었다. 함수가 두 번 세 번씩 호출된 것,, 문제가 무엇일까,, 해결부터 해야 하나,,검색해보니 같은 문제가 되게 많이 나왔다. 나만

velog.io

 

4. 파라미터

on은 파라미터를 넘겨줄 수 있다.

var EventEmitter = require('events');

const custom_event = new EventEmitter;
custom_event.on('event', (a, b) => {
    console.log(a, b);
    //   a b
});
custom_event.emit('event', 'a', 'b');

addEventListener은 바로 파라미터를 넘겨줄 수 없다. 함수를 따로 만들고 내에 함수를 집어넣어줘야 한다.

const p1 = 5;
const p2 = 7;

document.getElemetById('btn').addEventListener('click', () => {
    myFunction(p1, p2);
}

function myFunction(a, b) {
    let result = a * b;
    document.getElementById('text').innerHTML = result;
}

 

5. 이벤트 제거

on은 이벤트를 제거할 수 있다.

event.remove() 혹은 custom_event.removeListener(event)

 

addEventListener도 가능.

addEventListener ↔ removeEventListener()

element.removeEventListener('event', listener);

 

혹은

$(element).off()

여기서 말하는 element는 아래와 같은 형태의 element. HTML에 있는 element를 말하는 거임. (=객체)

element = document.getElementById('element id');

 

6. 리스너의 this

on은 리스너에서의 this는 해당 버튼을 가리키지만

addEventListener의 this는 버튼이 아니다. 타겟이 되는 element를 가리킨다.

var EventEmitter = require('events');

const custom_event = new EventEmitter;
custom_event.on('event', () => {
    console.log(this);
    //     MyEmitter {
    //     domain: null,
    //     _events: { event: [Function] },
    //     _eventsCount: 1,
    //     _maxListeners: undefined
});
custom_event.emit('event', 'a', 'b');

 

요약

항목 on (=addListener) onclick addEventListener
콜백함수 개수 여러 개 1 여러 개
구형 브라우저 지원   O X
이벤트 중복 O X X
파라미터 넘기기 O X X
이벤트 제거 O X O
리스너의 this 해당    element

 

 

 

 


참고 자료

 

Event 중 on 과 addEventListener 차이

_btn.addEventListener("click",handleClick); _btn.addEventListener("rollover",handleOver); _btn...

blog.naver.com

 

[JS] onclick과 addEventListener 비교

onclick과 addEventListener 비교자바스크립트에서 클릭 이벤트를 줄 때 어떤 방식을 사용하는가?onclick을 사용할 수도, addEventListener를 사용할 수도 있지만, 어떤 것을 사용하든 이 두 가지가 서로 어떻

jess2.github.io

 

[js] onclick · addEventListener 비교 사용법

이벤트 리스너는 이벤트가 발생했을 때 그 처리를 담당하는 함수를 가리키며, 이벤트 핸들러(event handler)라고도 합니다. 이벤트가 특정 element에서 발생하면, 웹 브라우저는 그 요소에 등록된 이

goddino.tistory.com

 

JavaScript DOM EventListener

JavaScript HTML DOM EventListener The addEventListener() method Example Add an event listener that fires when a user clicks a button: document.getElementById("myBtn").addEventListener("click", displayDate); Try it Yourself » The addEventListener() method

www.w3schools.com

 

(JS) addEventListener() vs onclick()

이 글을 작성하게 된 계기 지난 1월 18일에 있었던 김성호 선임님이 해주신 자바스크립트 강의를 들으면서 직접 질문했었던 궁금한 점을 다시 정리해 보려고 작성하였습니다. 잘못된 내용이 포

hanjungv.github.io

 

[Node.js] 이벤트(Event) 이해하기

노드에서 Event란? 노드에서는 대부분의 이벤트를 비동기 방식으로 처리합니다. 또한, 비동기 방식으로 이벤트를 전달합니다. 이벤트는 한쪽에서 다른 쪽으로 알림 메시지를 보내는 것과 비슷합

stickie.tistory.com

 

Events | Node.js v15.14.0 Documentation

Events# Source Code: lib/events.js Much of the Node.js core API is built around an idiomatic asynchronous event-driven architecture in which certain kinds of objects (called "emitters") emit named events that cause Function objects ("listeners") to be call

nodejs.org

 

(JavaScript) 이벤트 리스너와 콜백(event listener, callback)

안녕하세요. 이번 시간은 이벤트 리스너와 콜백 차례입니다. 지금까지는 이벤트 리스너를 안 다뤘습니다만 이제 다룰 때가 된 것 같습니다. 이벤트 리스너와 콜백 방식도 자바스크립트에서 많

www.zerocho.com

 

 

DOM, event - addEventListener를 쓰자

이 경우 직접적으로 HTML상에 함수를 실행하라고 명시하는것인데가독성이 떨어지고 이벤트를 단 하나밖에 지정할 수 없다는 단점이 있음.우선 DOM을 이용해 요소를 get한다. 그리고 그 변수를 이

velog.io

 

 

이벤트 처리 - 이벤트 핸들러(event handler), 이벤트 리스너(event listener), 이벤트 리스너 등록 방법,

이벤트 핸들러(event handler) ·      이벤트가 발생했을 때 그 처리를 담당하는 실행 함수를 가리킵니다. ·      특정 요소에서 발생한 이벤트를 처리하기 위해서는 이벤트 핸들러(event handler)

codedragon.tistory.com

이벤트 처리기

 

이벤트 처리기 [정보통신기술용어해설]

 

www.ktword.co.kr

이벤트 객체

 

13.2 이벤트 - 이벤트 객체

event 객체 DOM과 관련된 이벤트가 발생하면 관련 정보는 모두 event객체에 저장됩니다. 이벤트 발생 요소, 이벤트 타입, 이벤트 관련 데이터도 저장됩니다. ex) 마우스 이벤트 -> 마우스의 위치정보

blog.sonim1.com

 

반응형

'Front-End: Web > JavaScript' 카테고리의 다른 글

객체와 생성자 함수  (0) 2021.04.16
[작성중]프로토타입(Prototype)  (0) 2021.04.16
jQuery란 무엇일까?  (0) 2021.03.19
window 객체 & BOM  (0) 2021.03.19
JavaScript Error  (0) 2020.10.15