자바스크립트 이벤트 델리게이션 패턴
자바스크립트 이벤트 델리게이션 패턴
이벤트 델리게이션 패턴은 자바스크립트의 대표적인 디자인 패턴 중 하나입니다.
최근 HTML, CSS를 조작하는 웹에서 사용자의 '클릭', '호버' 등과 같은 동적인 이벤트를 관리하기 위해서 DOM에 이벤트를 작성하는 '이벤트 리스너(Event Listener)'가 있습니다. 이벤트 델리게이션 패턴은 이 이벤트 리스너를 보다 더 효율적으로 관리하기 위한 디자인 패턴입니다.
자바스크립트 이벤트 리스너
먼저, 자바스크립트의 이벤트 리스너에 대해 알아보겠습니다.
이벤트 리스너의 말 그대로 이벤트가 발생하기까지 대기하고 있습니다. 여기에서 이벤트란, 사용자가 브라우저에 하는 행동을 의미합니다.
이벤트 리스너가 엘리먼트에 추가되어 있다면 엘리먼트가 클릭되거나 마우스가 호버되고 더블클릭 등이 일어났을 때 해당 이벤트에 연결되어 있는 이벤트 리스너가 실행시킬 것입니다.
사용자가 버튼을 눌렀을 때 알림을 띄우는 리스너의 경우 다음과 같이 작성해야 할 것입니다.
- 버튼에 '클릭 이벤트'에 대한 이벤트 리스너를 작성합니다. 이렇게 하면 사용자가 버튼을 클릭할 때까지 이벤트 리스너가 대기하고 있습니다.
- 사용자가 버튼을 '클릭'했을 경우, 클릭 이벤트에 등록된 '이벤트 리스너'가 실행됩니다.
자바스크립트는 이와 같은 방법을 이용해 비동기적인 사용자의 액션을 처리할 수 있습니다. 이러한 패턴을 옵저버 패턴(관찰자 패턴)이라 합니다.
자바스크립트 이벤트 프로세스와 이벤트 전파를 중단하는 방법에 대해서는 아래 링크를 참고해주세요.
자바스크립트 이벤트 델리게이션 패턴
이제, 이 포스트의 주제인 이벤트 델리게이션 패턴에 대해서 알아보겠습니다. 이벤트 델리게이션은 이벤트 전파 과정과 이벤트 버블링, 이벤트 캡쳐링의 개념을 알고 있다면 어렵지 않게 이해할 수 있습니다. 우선, 다음 예제를 살펴보겠습니다.
<body>
<button id="btn1">Btn1</button>
<button id="btn2">Btn2</button>
<button id="btn3">Btn3</button>
</body>
body
안에 3개의 button
이 존재하는 경우, 각각의 버튼에 서로 다른 기능을 수행하도록 이벤트 리스너를 설정하고 싶다면 다음과 같이 이벤트 리스너를 작성하면 됩니다.
document.querySelector("#btn1").addEventListener("click", function() {
console.log("click btn1");
});
document.querySelector("#btn2").addEventListener("click", function() {
console.log("click btn2");
});
document.querySelector("#btn3").addEventListener("click", function() {
console.log("click btn3");
});
하지만, button의 개수가 많아지고 심지어 DOM Element가 동적으로 변화하고 있는 상황이라면 이벤트 리스너를 하나하나 등록하는 것은 브라우저의 메모리를 많이 사용하게 될 것이고 곧 퍼포먼스 저하로 이어지게 될 것입니다.
이를 해결할 때 주로 사용되는 패턴이 이벤트 델리게이션 패턴입니다. 이벤트 델리게이션 패턴은 상위 엘리먼트에 이벤트를 준 뒤, 분기하는 것인데 버튼에 일일이 이벤트 리스너를 등록하지 않고 버튼을 감싸고 있는 body
에 이벤트 이스너를 등록해서 이벤트의 target 값을 이용해 버튼의 클릭 이벤트를 지정하는 것입니다.
이벤트 발생시에 전달되는 이벤트 객체에는 Target
이 명시되어 있어서 부모 노드로부터 캡쳐링을 통해 이벤트를 전달받더라도 이벤트가 어떤 엘리먼트에서 발생했는지, 어떨게 이벤트를 처리해야 하는지 알 수 있습니다.
이를 이용해 위에서 3개의 이벤트 리스너를 등록했던 코드를 다음과 같이 수정할 수 있습니다.
document.querySelector('body').addEventListener('click', function(event) {
var target = event.target || event.srcElement;
switch (target.id) {
case "btn1":
console.log("click btn1");
break;
case "btn2":
console.log("click btn2");
break;
case "btn3":
console.log("click btn3");
break;
default:
break;
}
event.stopPropagation();
}, true);
위와 같이 부모 엘리먼트에 하위 엘리먼트의 리스너를 작성하는 방식을 "이벤트 델리게이션 패턴"이라 하며, 이는 자바스크립트에서 퍼포먼스를 높이는 것에 있어서 중요한 역할을 차지하고 있습니다.
여러 프레임워크에서의 이벤트 위임
Backbone.js
, Ember.js
, React.js
와 같은 경우, 내부적으로 이벤트 위임을 하기 때문에 자체적으로 제공하는 이벤트 등록 방식을 사용하면 됩니다.
Angular.js
의 경우, 자체적으로 지원하지는 않지만 angular-event-delegate
모듈을 사용해 위임을 할 수 있습니다.
'Advanced > JavaScript' 카테고리의 다른 글
[JavaScript] 캘린더 만들기 - 한 주 구하기 (0) | 2020.12.20 |
---|---|
[JavaScript] 가변 인자 함수 (1) | 2020.11.16 |
JavaScript 이벤트 전파 중단 방법 (IE 대응 추가) (0) | 2020.11.10 |
자바스크립트 이벤트 버블링과 캡쳐 (0) | 2020.11.03 |
JavaScript child element mouseout 이슈 (0) | 2020.10.29 |
댓글
이 글 공유하기
다른 글
-
[JavaScript] 캘린더 만들기 - 한 주 구하기
[JavaScript] 캘린더 만들기 - 한 주 구하기
2020.12.20 -
[JavaScript] 가변 인자 함수
[JavaScript] 가변 인자 함수
2020.11.16 -
JavaScript 이벤트 전파 중단 방법 (IE 대응 추가)
JavaScript 이벤트 전파 중단 방법 (IE 대응 추가)
2020.11.10 -
자바스크립트 이벤트 버블링과 캡쳐
자바스크립트 이벤트 버블링과 캡쳐
2020.11.03