Event Listener

CDD·2023년 3월 12일
0

web-develop

목록 보기
3/11
post-thumbnail

Old EventHandling

나중에 ReactJS 에 관한 글을 작성하면서 Handling Event 에 대한 글을 한 번 더 적기는 하겠지만, 이번에 게시할 내용은 JS 내의 이벤트 핸들링 기능인 eventListener 에 관한 내용이다. Event는 말 그대로 어떠한 사건이 일어남을 의미하는데, 웹에서는 클릭과 같이 사용자로 인해 어떠한 행동이 트리거 되었을 때 특정 동작을 유도하는 식으로 사용된다. 사용자와 웹페이지 간의 상호작용을 만들어주는 기능이라고 보면 된다.

<button onclick="this.innerHTML = '클릭'">클릭 전</button>

간단한 예제코드로부터 먼저 알아보자면 onclick : 사용자가 '클릭'했을 때 이벤트가 발생한다면 현 <button>innerHTML 값을 '클릭'으로 바꾼다는 의미를 가지고 있다. 하지만 위와 같은 방법은 이해하기는 좋은 코드지만 현재는 저런 방법을 많이 쓰지 않는다고 한다. 주로 로직 구현은 JS에서 이루어지기에 별개의 JS 파일에서 따로 eventListener 을 설정해주고, 트리거가 될 이벤트를 설정해주는 식으로 사용한다. 예제를 만들기 위해서 HTMLinline 형태로 들어간 onclick은 잠시 빼주고, JS 코드를 작성해보자.

addEventListener

<!-- html -->

<!-- Button Elements -->
<button id = 'cdd-button'>클릭 전</button>
// index.js

// id 값을 활용하여 버튼을 찾는 querySelector
var cdd_button = document.querySelector("#cdd-button");

// 클릭시 이행 할 사용자 정의 함수
function click() {
  cdd_button.innerHTML = "click complete";
}

// 화살표 함수를 통해 간소화, 괄호 내에서 즉시 함수 선언을 해줄 수 있음
cdd_button.addEventListener("click", () => {
  alert("click !");
});

// 사용자가 정의한 함수명을 안에 넣어주면 해당 이벤트 시 이행함
cdd_button.addEventListener("click", clickFunc);

onclick 보다는 위와 같이 addEventListener을 현업에서도 쓰는 경우가 더 많다고 한다. 기본적인 사용 방법은 element.addEventListener('eventType', function)와 같은 형태로 사용한다. 전역 스코프로 사용하기도 하고, 함수 스코프 내 특정 조건에 의해 리스너를 정의할수도 있다.

button = document.querySelector('#submit-button');

function printSomething(e) {
  e.preventDefault(); // 기존 고유한 태그 동작 종료
  button.innerHTML = 'clicked';
}

button.addEventListener('click', printtext);

click 이벤트 뿐만 아니라 mouseover이나 mouseout 등 찾아보면 다양한 이벤트에 함수를 정의하여 사용할 수 있다. 위의 코드에서 볼 수 있는 preventDefault()는 e의 동작을 정지시키는 메서드 역할을 하는데, 여기서 인자값으로 온 e는 click event를 의미하며, e.target과 같은 키워드를 통해 이벤트 대상이 되는 요소, 즉 버튼의 값을 활용하여 값을 직접적으로 수정하거나 업데이트 시킬 수 있다. 위에서 preventDefault()가 쓰인 이유는 버튼을 눌렀을 시 자동으로 페이지가 reload() : 새로고침 되는데, 이를 방지하기 위해 사용된다. 추가적으로 stopPropagation() 메서드를 활용하면 상위 요소로의 이벤트 전파까지 막을 수 있다.

querySelectorAll in addEventListener

element = document.querySelector('main div #header'); // 단일 값
elements = document.querySelectorAll('#footer'); // 복수 값

특정 요소를 들고 오고 싶을 때 getElementsById와 같은 방법이 있지만 해당 방법은 가지고 오는 요소 태그의 종류에 따라 메서드명을 다르게 지정해줘야 한다는 번거로움이 있다. 그래서 보통은 querySelectorquerySelectorAll을 통해 직접적인 경로를 작성하여 요소를 편하게 가져오곤 하는데, 성능적인 부분에서는 다소 부족한 부분이 있다고 한다. 무튼 단일 객체를 가져올 때는 큰 문제가 되지 않지만 querySelectorAll을 통해 다중 객체를 가져오게 되면 EventListener를 작성하는데 약간의 문제가 생기게 된다. 한 가지 예를 들어보도록 하자.

elements = document.querySelectorAll('#footer'); // 복수 값
elements.addEventListener('mouseout', () => { ... });

대충 이렇게 적어놓으면 가져온 모든 객체들에 EventListener이 자동적으로 할당 될 것이라는 착각을 하곤 한다. 하지만 각 요소에 일일이 적용 시켜주는 것이 아니라면 제대로 기능이 작동하지 않는 문제점이 발생한다. 위의 코드도 마찬가지인 잘못된 예시이다. 그러면 이를 해결하기 위해서는 어떻게 해야 할까? 정답은 바로 for loop을 활용하여 각 요소들에 리스너를 넣어줘야 한다.

elements = document.querySelectorAll("#footer"); // 복수 값

for (var i = 0; i <= elements.length; i++) {
  elements[i].addEventListener("mouseout", () => { ... });
}

이런식으로 말이다.

0개의 댓글