본문 바로가기

IT 관련/javascript & jquery

자바스크립트 이벤트 처리 javascript

자바스크립트 애플리케이션에서 이벤트 처리는 중요합니다. 모든 자바스크립트는 이벤트를 처리해서 UI를 구현하므로 웹 개발자들은 이벤트 핸들러 코드를 작성하거나 수정하는 일이 잦은 편입니다. 그런데 안타깝게도 자바스크립트 초기부터 지금까지 개발자들은 이벤트 처리를 그리 중요하게 여기지 않습니다. 자바스크립트에 아키텍처의 전통적인 컨셉을 적용할 때도 이벤트 처리 방법은 아주 조금만 바꿨습니다. 게다가 저마다 개발자가 사용해본 방법 위주로 이벤트 처리를 해서 유지보수성이 상당히 좋지 않습니다.

 

1. 고전적인 방법

개발자 대부분이 이벤트 핸들러에 전달되는 이벤트 객체에 대해 잘 알고 있습니다. 이벤트 객체에는 이벤트 타입에 따른 부가 데이터가 이벤트 타겟 등 이벤트와 관련한 모든 정보가 있습니다. 아무스 이벤트는 이벤트 객체에 관한 추가적인 좌표 정보를 나타내며, 키보드 이벤트는 입력된 키에 관한 정보를 나타냅니다. 또 터치 이벤트는 터치가 발생한 좌표와 지속 시간에 대한 정보를 나타냅니다. 이 모든 정보는 사용자 입력에 따라 정확하게 UI를 동작하도록 하는 데 사용됩니다.

 

그러나 대부분 이벤트 객체가 제공하는 많은 정보 중에 극히 일부분만 사용합니다.

// 나쁜 예

function handleClick(event) {

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

    popup.style.left = event.clientX + "px";

    popup.style.top = event.clientY + "px";

    popup.className = "reveal";

}

 

addListener(element, "click", handleClick);

 

 

위 예제에서는 이벤트 객체에서 clientX, clientY 프로퍼티만 사용합니다. 이 프로퍼티는 사용자에게 요소를 보여주기 전에 페이지에서 요소의 위치를 조정하는 데 사용합니다. 이 코드만으로는 간단하고 문제없어 보이지만, 실제 활용하기 전에는 제한 사항이 많아서 사용하기 어려운 나쁜 패턴입니다.

 

2. 애플리케이션 포직을 분리

위 예제는 이벤트 핸들러가 애플리케이션 로직을 포함하는 문제가 있습니다. 애플리케이션 로직은 사용자의 액션보다는 애플리케이션 자체에 대한 기능을 다루어야 합니다. 그런데 위 코드의 애플리케이션 로직은 팝업창을 특정 위치에 보여주고 있습니다. 물론 이 코드는 사용자가 특정 요소를 클릭할 때 수행되지만, 이 코드가 다른 곳에서 필요할 수도 있습니다.

 

나중에 다른 사용자 액션에서 이 로직이 필요하면 재사용할 수 있어야 하므로 이벤트 핸들러에서 애플리케이션 로직은 무조건 분리해야 합니다. 

예들 들어 나중에 클릭할 때뿐만 아니라 특정 요소 위에서 커서가 움직이거나 키보드의 특정 키를 눌렀을 때도 팝업창을 나타나게 해야 할 수도 있는데 이 때 실수로 다른 이벤트에 마우스 클릭 이벤트에 맞춰 개발된 핸들러를 등록해야 하는 일이 생길 수도 있습니다.

 

또 이벤트 핸들러에 애플리케이션 로직이 있으면 테스트하기 어려워집니다. 테스트는 기능이 정확하게 동작하는지 매번 요소를 클릭하는 번거로움이 있으면 안되고 테스트할 기능만 바로 실행할 수 있어야 합니다. 이때, 애플리케이션 로직이 이벤트 핸들러 안에 있으면 이벤트를 발생시켜야만 테스트를 진핼할 수 있습니다.

물론 테스트 프레임워크에 따라 이벤트를 자체적으로 발생시켜주기도 하지만 좋은 방법이라 할 수 없습니다.

간단하게 함수를 호출하는 것만으로도 해당 기능을 수행할 수 있어야 합니다.

 

이벤트 처리 코드와 애플리케이션 로직은 확실히 분리해야 합니다. 그 첫단계로 다룬 예제를 리팩터링 해보겠습니다.

팝업창을 처리하는 코드는 함수로 따로 분리하고, One-Gloval 접근법을 사용해 하나의 전역 객체만 사용하도록 수정합니다. 여기서 이벤트 핸들러는 애플리케이션 로직 처리 함수처럼 전력 객체에 두어야 합니다. 그러면 다음 예제처럼 전역 객체에는 두 개의 메서드가 있게 됩니다.

 

// 리팩토링

var MyApplication = {

    handleClick: function(event) {

        this.showPopup(event);

    },

 

    showPopup: function(event) {

        var popup = document.getElementById("popup");

        popup.style.left = event.clientX + "px";

        popup.style.top = event.clientY + "px";

        popup.className = "reveal";

    }

};

 

addListener(element, "click", function(event) {

    MyApplication.handleClick(event);

});

 

이벤트 핸들러에 있던 애플리케이션 로직을 MyApplication.showPopup() 메서드로 옮겼습니다. 이제 MyApplication.handleClick() 메서드는 다른 로직 없이 MyApplication.showPopup() 메서드만 호출합니다.

이벤트 핸들러에서 애플리케이션 로직이 분리됨에 따라 다른 이벤트에서 팝업창을 띄우는 로직이 필요하면 MyApplication.showPopup()를 호출하게 하면 됩니다. 그러나 이건 첫 단계일 뿐이고 변경할 부분이 더 남았습니다.

 

다음 시간에는 이번에 이어서 함수를 개선해보겠습니다.

 

그럼 이만.

끝.

 

'IT 관련 > javascript & jquery' 카테고리의 다른 글

코드에서 구성 데이터 분리하기  (0) 2022.01.28
javascript 브라우저 탐지  (0) 2022.01.21
[javascript] try...catch문  (0) 2022.01.14
javascript NULL 비교  (0) 2022.01.12
가독성 좋은 javascirpt 이름 규칙  (0) 2022.01.10