Button onclick 함수 - Button onclick hamsu

우리가 사용하는 웹 사이트나 웹 애플리케이션에서는 수많은 이벤트가 발생합니다. 사용자가 마우스나 키보드로 일으킬 수 있는 이벤트도 있고, 브라우저 스스로도 웹페이지를 로딩하면서 여러 이벤트를 발생시킵니다.

이번 포스팅에서는 이렇게 웹에서 다양한 이유로 발생하는 이벤트를 처리하는 여러가지 방법에 대해서 알아보겠습니다.

HTML 이벤트 속성

먼저 가장 고전적이지만 사용하기 간단한 방법부터 알아볼까요?

HTML 요소(element)에서 발생하는 이벤트를 처리하는 가장 쉬운 방법은 HTML의 이벤트 속성을 활용하는 것입니다. on<이벤트 타입명> 형태를 갖는 이벤트 속성은 HTML의 모든 요소에 사용이 가능하며, 해당 타입의 이벤트 발생 시 실행할 자바스크립트 코드(이벤트 핸들러)를 속성 값으로 설정해줄 수 있습니다.

예를 들어, 다음 <button> 요소는 클릭했을 때, 브라우저 알람으로 클릭이라는 메시지가 뜰 것입니다.

<button onclick="alert(textContent)">클릭</button>

다른 예로, 다음 <input> 요소는 클릭했을 때, 브라우저 콘솔에 입력한 내용이 출력될 것입니다.

<input name="test" onchange="console.log(value)" />

여기서 자바스크립트 코드에 사용된 textContentvalue는 이벤트가 발생한 HTML 요소의 속성입니다. 이렇게 HTML의 이벤트 속성으로 사용된 자바스크립트 코드에서는 이벤트가 발생한 요소에 자연스럽게 접근할 수 있습니다.

이처럼 HTML 이벤트 속성은 간단한 코드를 실행하기에는 매우 간편하지만 이벤트 발생 시에 실행할 로직이 복잡한 경우에는 그닥 추천되지는 않습니다. 그리고 순수하게 HTML 기반인 이 방법에는 한가지 큰 제약 사항이 있는데 바로 이벤트 핸들러를 한 번 설정하면 제거하는 것이 어렵습니다. 다시말해, 이벤트 핸들러를 제거하려면 다음에 소개드릴 자바스크립트의 도움이 필요하게 됩니다.

JavaScript 이벤트 속성

HTML 요소에서 발생하는 이벤트를 처리하는 두 번째 방법은 자바스크립트의 DOM 노드의 이벤트 속성을 활용하는 것입니다.

우선 위에서 작성한 HTML 코드에서 이벤트 속성을 모두 제거하겠습니다.

그 다음, 자바스크립트로 <button> 요소를 선택 후 onclick 속성에 이벤트 핸들러 함수를 지정해주면 됩니다.

const buttonEl = document.querySelector("button");
buttonEl.onclick = function (event) {
  alert(this.textContent);
  // alert(event.target.textContent);
};

이벤트가 발생한 요소에 접근할 때는 this 키워드나 함수의 인자로 넘어온 event 매개 변수의 target 속성을 사용할 수 있습니다.

<input> 요소에도 마찬가지로 onchange 속성을 제거하겠습니다.

이번에는 코드가 좀 더 깔끔해 보이도록 function 키워드 대신에 => 기호를 사용하는 람다(lambda) 함수를 사용해보겠습니다.

const inputEl = document.querySelector("input");
inputEl.onchange = (event) => console.log(event.target.value);

이벤트 핸들러로 람다 함수를 사용할 때 주의할 점은 더 이상 this 키워드로 이벤트가 발생한 요소에 접근할 수 없다는 것입니다. 따라서 이벤트가 발생한 요소에 접근할 때는 반드시 event.target을 사용해야 합니다.

이벤트 핸들러를 제거할 때는 선택한 HTML 요소의 이벤트 속성을 null로 설정해주면 됩니다.

JavaScript 이벤트 함수

마지막으로 소개해드릴 방법은 자바스크립트의 DOM 노드를 대상으로 addEventListener() 함수를 호출하는 것입니다.

addEventListener() 함수는 첫 번째 인자로 이벤트 타입명을 두 번째 인자로 이벤트 핸들러를 받습니다.

따라서 위에서 onclick 속성에 지정했던 이벤트 핸들러 함수를 다음과 같이 click이라는 이벤트 타입명과 함께 addEventListener() 함수에 넘길 수가 있습니다.

const buttonEl = document.querySelector("button");
buttonEl.addEventListener("click", function (event) {
  alert(this.textContent);
});

물론 람다 함수로 이벤트 핸들러를 넘길 수도 있으며, 마찬가지로 이 때는 this 키워드로 이벤트가 발생한 요소에 접근할 수 없다는 점 주의해야 합니다.

const inputEl = document.querySelector("input");
inputEl.addEventListener("change", (event) => console.log(event.target.value));

addEventListener() 함수를 사용할 때 큰 이점은 바로 하나의 DOM 노드를 대상으로 이 함수를 여러번 호출할 수 있어서, 해당 HTML 요소에서 이벤트가 발생했을 때 여러 이벤트 핸들러를 실행할 수 있다는 것입니다.

예를 들어, <input> 요소에서 change 타입의 이벤트가 발생했을 때 이벤트 내용을 로깅하도록 logEvent라는 함수를 이벤트 핸들러로 추가해보겠습니다.

function logEvent(event) {
  console.log({
    type: event.type,
    name: event.target.name,
    value: event.target.value,
  });
}
inputEl.addEventListener("change", logEvent);

이제, <input> 요소에 안녕이라고 입력하면 아래와 같이 브라우저 콘솔에 이벤트 내용이 출력이 될 것입니다.

>> "안녕"
>> {
  "type": "change",
  "name": "test",
  "value": "안녕"
}

이벤트 핸들러를 제거할 때는 removeEventListener() 함수를 사용하여 이벤트 타입명과 이벤트 핸들러를 넘기면 됩니다.

inputEl.removeEventListener("change", logEvent);

마치면서

지금까지 웹페이지에서 발생하는 이벤트를 처리하는 대표적인 3가지 방법에 대해서 살펴보았습니다. 각 방법의 장단점을 간단하게 정리해보면,

  • HTML 이벤트 속성: 가장 고전적이지만 이벤트 핸들러가 간단할 경우 간편하게 게 쓸 수 있음. 이벤트 핸들러를 제거하기 어려움.
  • JavaScript 이벤트 속성: 위와 유사하나 자바스크립트를 사용하며 쉽게 이벤트 핸들러를 제거할 수 있음.
  • JavaScript 이벤트 함수: 여러 이벤트 핸들러를 유연하게 추가하거나 제거할 수 있음. 사용법이 상대적으로 어려움.

개인적으로는 저는 가장 강력한 마지막 방법을 추천드리고 싶지만 첫번째나 두번째 방법도 잘 숙지해두시면 기존에 작성된 코드를 읽을 때 도움이 되실 겁니다. 이벤트 처리는 어떤 프레임워크로 웹 개발을 하든 반드시 알아야 할 부분이오니 이번 기회에 잘 정리해두셨으면 좋겠습니다.