[이벤트 다루기: addEventListener] - JavaScript

ain·2022년 6월 17일
0

JavaScript

목록 보기
2/4
post-thumbnail

이벤트를 쓰는 이유

우리는 HTML과 CSS로 정적 웹사이트를 만들어보면 이런 생각이 들 수밖에 없다.

'아, 이 버튼은 클릭하면 팝업이 튀어나왔으면 좋겠는데….'
'새로고침을 해도 로그인 상태가 유지됐으면 좋겠는데….'
'100개나 되는 이미지를 한꺼번에 불러오고 싶지 않은데….'

생활코딩의 강의를 들으면서 '우리의 욕심은 끝이 없다'라고 말씀하셨던 게 기억이 나는데, 직접 정적 웹사이트를 만들어봤다면 이 말에 동감할 것이다.
물론 HTML의 <a>태그로 페이지 간의 이동이 가능하고, CSS의 hover나 focus 선택자로 소소한 애니메이션을 만들 수도 있지만, 이것들로만 구성되어있는 웹페이지는 정말 불편하고 재미도 없을 것 같다.
웹사이트를 조금 더 실용적이고, 재미라는 요소를 더하기 위해 자바스크립트를 사용한다고 생각하면 동적인 웹페이지를 만들면서도 더 창의적인 도전을 할 수 있다고 생각한다. 왜냐하면 자바스크립트는 HTML, CSS의 한계를 뚫어주니까…!

syntax

eventTarget.addEventListener('eventType', function)

-> 이벤트를실행할타겟.addEventListener('이벤트타입', 실행할함수)

  • eventTarget(이벤트 타겟)은 해당 이벤트를 적용할 DOM을 가져와 준다.
  • eventType(이벤트 타입)은 말 그대로 어떤 타입의 이벤트를 적용할 것인지 써주면 된다. 대표적으로 click DOMContentLoad, scroll submit등등이 있다. 타입을 써줄 때는 따옴표를 잊지 말고 감싸줘야 한다.
  • click: 요소를 클릭하면 이벤트 발생.
  • DOMContentLoaded: 페이지가 새로 로딩될 때마다 이벤트 발생.
  • scroll: 스크롤을 하면 이벤트 발생.
  • submit: 양식을 전송하면 이벤트 발생. (ex: input type이 submit일 때 submit 버튼을 누르는 것과 같음)
  • function(실행할함수)에는 이벤트를 발생시켰을 시 실행할 동작을 가져와 준다.

활용

실행시킬 함수를 변수에 저장.

	const button = document.querySelector('button');
    //1번
    const print = () => {
    	console.log('print!');
    }
	button.addEventListener('click', print);

OR
addEventListener에 바로 적용

	//2번
	button.addEventListener('click', () => {
   		console.log('print!');
   });

만약 이렇게 간단한 코드가 아닌 복잡하고 긴 코드를 작성해야 한다면 1번 코드처럼 함수를 따로 만들어서 변수나 배열에 저장해서 재사용이 가능하게끔 만들어주는 게 좋다. 하나의 evnetListener 메소드에 정리되지 않은 코드를 집어넣는다면 재사용도 쉽지 않고 가독성도 좋지 않을 것이다.
재사용(reusable blocks of code)이란 해당 함수를 다른 요소에도 쓰이는 것을 말하는데 코드의 조각을 하나의 블록에 저장하여 그 코드를 언제 어디서든 호출하여 재사용할 수 있는 것을 말한다.

차례대로 동작을 실행해야 하는 경우

화살표 함수로 간단하게 작성할 수 있다.

	eventTarget.addEventListener('eventType', () => {
    	firstFunction();
        secondFunction();
        if(...) {
        	thirdFunction();
        } else {
        	forthFunction();
        }
    })

계산기로 예를 들면, 1 + 1을 한 후 All Clear 버튼을 누르면 두 가지 동작이 실행된다. 첫 번째로 숫자와 연산자를 초기화 시켜주는 동작, 두 번째로 화면의 숫자를 0으로 바꿔주는 동작. 이렇게 차례대로 읽혀서 마지막 함수가 최종적으로 실행된다.

하나의 요소에 여러개 이벤트 적용

	const clicked = () => {
    	console.log('click event is on');
    };

	const mouseOvered = () => {
    	console.log('mouse event is on');
    }

	eventTarget.addEventListener('click', clicked);
	eventTarget.addEventListener('mouseover', mouseOvered);

하나의 요소에 동일 이벤트, 다른 함수 적용

	const console = () => {
    	console.log('first click');
    };

	const alert = () => {
    	alert('second click');
    }

//첫 번째 방법
	eventTarget.addEventListener('click', console);
	eventTarget.addEventListener('click', alert);
//두 번째 방법
	eventTarget.addEventListener('click', () => {
    	console();
    	alert();
    });

두 번째 방법처럼 하나의 메소드에 화살표 함수로 혹은 익명함수를 사용하면 가독성이 좋다. 대부분 화살표 함수를 많이 쓰지만, 한가지 주의할 점이 있다.

  • this를 쓸 때, this가 가리키는 대상이 다르다. 익명함수를 쓸 때는 this가 eventTarget을 가리키지만, 화살표 함수에서는 대상이 상위 스코프인 Window 객체를 가리킨다.

화살표 함수

const button = document.querySelector('button');
	button.addEventListener('click', () => {
    	console.log(this)
    });
							결과↓

window객체

익명함수

	button.addEventListener('click', function () {
    	console.lof(this); //<>
    });
								결과↓

버튼DOM

addEventListener 메소드에서 함수는 어떻게, 언제 쓰느냐에 따라 쓰는 방식이 매우 다양하니 자신의 코드에 맞게 적절히 사용하길...😀

여러 개의 동일 요소에 같은 이벤트 적용

예를 들어 같은 클래스를 가진 요소가 여러 개 있고, 전부 다 이벤트를 적용해야 한다면, 하나하나 addEventListener를 적용할 수는 없다. 예를 들어 버튼이 100개가 있다면 addEventListener를 100개나 쓸 수는 없을 것이다??

이 같은 경우 DOM을 가져온 다음 forEach 메소드로 짧게 구현할 수 있다.

const getAll = (target) => document.querySelectorAll(target);
// 이렇게 유틸 함수를 써놓고 getAll(target)으로 짧게 사용할 수 있다.
const buttons = getAll('.btn');
const clicked = () => {
	console.log('clicked!');
};
buttons.forEach((button) => {
	button.addEventListener('click', clicked);
});
/*
여기서 button은 DOM에서 querySelectorAll로 가져온 buttons 들에
하나하나 접근해서 가져온 `하나의` button이다.
그래서 eventListener를 걸 때에는 buttons가 아닌 button에 걸어야 한다.
*/

event 매개변수

addEventListener는 함수 부분에서 event 또는 e 라는 매개변수를 받을 수 있다.

button.addEventListener('click', (event) => {
	console.log(event);
})

이 매개변수를 콘솔에 출력해보면 이런 결과가 나온다.
e를 콘솔에 찍은 결과

이 값들에 접근하는 방법은 간단하다. event 또는 e 뒤에 점(.)을 찍고 해당 key를 써주면 된다. 예를 들어 event의 target이 궁금할 때는 event.target을 시도해보면 된다.

button.addEventListener('click', (event) => {
	console.log(event.target);
})

그러면 현재 이벤트가 걸려있는 button 요소가 출력될 것이다.

활용

웹사이트에 팝업이 떴을 때 팝업의 바깥 배경 쪽을 클릭하면 팝업이 꺼지는 코드를 짠다고 할 때, window를 클릭했을 때 event.target이 어떤 요소인지 알아야 함수를 실행할 수 있을 것이다. 그럴 때 콘솔로 event.target을 출력해서 알아낸 후 사용한다.

window.addEventListener('click', (event) => {
	console.log(event.target)

이제 여기서 나온 event.target이 위에서 콘솔에 찍힌 요소와 같다면 함수를 실행하는 것으로 코드를 짜준다.

window.addEventListener('click', (event) => {
	if(event.target === 요소) {
    	팝업꺼지는함수();
    }

Event Type과 사용법

Event Type이 무엇이 있는지, 또 어떻게 쓰이는지를 정리해보았다. (2022년 6월 18일 기준) 지금까지 공부해왔던 위주로 정리했기 때문에 많지는 않다. 이후에 또 공부한 만큼 추가할 예정이다.

  • click | 이벤트 타겟을 '클릭'하면 이벤트 발생.
    활용: 닫기 버튼, 메뉴 버튼, 토글 버튼, 이전 다음 버튼 등등
  • scroll | 이벤트 타겟을 '스크롤' 하면 이벤트 발생.
    활용: 무한 스크롤, 프로그래스 바(블로그의 페이지 상단에서 많이 보임) 등등
  • load | html 문서를 완전히 불러왔을 때 이벤트 발생. 이때 DOMContentLoaded와 다르게 CSS나 이미지, frame 요소와 같은 하위프레임(sub frame)의 로딩이 완료되고 나서 이벤트 발생.
    활용: localStorage를 이용한 애니메이션 또는 트랜지션(transition) 상태(state) 유지.
  • keydown | 키보드의

이 외에도 keyup(키를 눌렀다가 땠을 때), mouseover(hover), mouseout(마우스가 hover 됐다가 빠져나왔을 때) 등등이 있다.

마무리

이처럼 addEventListener메소드 만으로도 재미없던 정적 웹사이트를 활발하게 만들 수 있다. 몇 달 전 자바스크립트의 도 몰랐던 때, click 이벤트가 실행됐을 때의 그 짜릿함이 아직도 생생하다. 그때의 느낌과 마음가짐으로 초심을 잃지 않고 (지금으로선) 막막한 앞길을 헤쳐 나가야겠다.

참고

profile
프론트엔드 개발 연습장 ✏️ 📗

2개의 댓글

comment-user-thumbnail
2023년 10월 28일

알기쉽게 잘 정리되어있어서 필요한 타이밍에 정말 많은 도움이 되었습니다. 다른 포스터들도 다 봐야겠다는 생각이 드네요. 감사합니다!!

1개의 답글