Super Kawaii Cute Cat Kaoani
본문 바로가기
💻 Programming/Javascript

인터랙티브 자바스크립트 : 이벤트

by wonee1 2024. 6. 8.
728x90

<인터랙티브 자바스크립트>

 

 

 

이벤트와 이벤트 핸들링, 그리고 이벤트 핸들러

  • 이벤트 : 웹 페이지에서 발생하는 대부분의 일(사건)들      ex) 버튼 클릭, 스크롤, 키보드 입력, ...
  • 이벤트 핸들링 : 자바스크립트를 통해 이벤트를 다루는 일
  • 이벤트 핸들러 : 이벤트가 발생했을 때 일어나야하는 구체적인 동작들을 표현한 코드. 이벤트 리스너(Event Listener)라고도 부른다.

 

이벤트가 발생했을 때 어떤 특별한 동작을 하도록 이벤트를 다루는 것을 이벤트 핸들링이라고 부른다

구체적인 동작들을 코드로 표현한 함수 부분을 이벤트 핸들러라고 부른다

 

* 이벤트 핸들링은 js 코드 뿐만아니라 html 코드에도 작성할 수 있긴 하지만 코드의 유지보수를 위해서 js에 작성하는 편

 

 

 

 

 

 

이벤트 핸들러 등록하기 

 

 

onclick 프로퍼티를 사용하지 않고 이벤트 핸들러를 등록하는 한 가지 방법

 

addEventListener 메소드를 활용하는 것

//이벤트 핸들러 등록하기 

let btn= document.querySelector('#myBtn');

function event1(){
    console.log('Hi Codeit!');
}

function event2(){
    console.log('Hi again!');
}

//elem.addEvendListner(event, handler)

btn.addEventListener('click',event1);
btn.addEventListener('click',event2);

//elem.removeEventListner(event, handler)
btn.removeEventListener('click',event2); 
btn.removeEventListener('click',event2()) ; x

 

• 메소드를 여러 개 호출하게 되면 여러 개의 독립적인 이벤트 핸들러를 등록할 수 있게 된다

• 이벤트를 삭제할 때 반드시 등록할 때 사용했던 핸들러를 전달 할 것

• 이벤트 핸들러엔 함수 이름만 전달해줘도 된다

 

 

이벤트 종류 

 

마우스 이벤트

mousedown 마우스 버튼을 누르는 순간
mouseup 마우스 버튼을 눌렀다 떼는 순간
click 왼쪽 버튼을 클릭한 순간
dblclick 왼쪽 버튼을 빠르게 두 번 클릭한 순간
contextmenu 오른쪽 버튼을 클릭한 순간
mousemove 마우스를 움직이는 순간
mouseover 마우스 포인터가 요소 위로 올라온 순간
mouseout 마우스 포인터가 요소에서 벗어나는 순간
mouseenter 마우스 포인터가 요소 위로 올라온 순간 (버블링이 일어나지 않음)
mouseleave 마우스 포인터가 요소에서 벗어나는 순간 (버블링이 일어나지 않음)

 

 

키보드 이벤트

keydown 키보드의 버튼을 누르는 순간
keypress 키보드의 버튼을 누르는 순간 ('a', '5' 등 출력이 가능한 키에서만 동작하며, Shift, Esc 등의 키에는 반응하지 않음)
keyup 키보드의 버튼을 눌렀다 떼는 순간

 

 

포커스 이벤트

focusin 요소에 포커스가 되는 순간
focusout 요소로부터 포커스가 빠져나가는 순간
focus 요소에 포커스가 되는 순간 (버블링이 일어나지 않음)
blur 요소로부터 포커스가 빠져나가는 순간 (버블링이 일어나지 않음)

 

 

입력 이벤트

change 입력된 값이 바뀌는 순간
input 값이 입력되는 순간
select 입력 양식의 하나가 선택되는 순간
submit 폼을 전송하는 순간

 

 

스크롤 이벤트

scroll 스크롤 바가 움직일 때

 

 

윈도우 창 이벤트

resize 윈도우 사이즈를 움직일 때 발생

 

 

 

 

이벤트 객체

 

 

이벤트를 제대로 다루기 위해선 이벤트에 대한 상세한 정보가 필요함

→ 웹 페이지에서 이벤트가 발생하면 그 이벤트와 관련된 다양한 정보를 담고 있는 이벤트 객체가 자동으로 만들어진다!

 

 

💡이벤트 핸들러가 되는 함수의 첫 번째 파라미터에는 항상 이벤트 객체가 전달된다

 

 

// 이벤트 객체 (Event Object)
const myInput = document.querySelector('#myInput');
const myBtn = document.querySelector('#myBtn');

function printEvent(event) {
  console.log(event); // 이벤트 객체 출력 
	//event.target.style.color = 'red';
}

myInput.addEventListener('keydown', printEvent);
myBtn.addEventListener('click', printEvent);

 

 

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>JS with Codeit</title>
</head>
<body>
  <div id="content" class="btns">
    <input type="text" id="myInput" placeholder="type anything">
    <button id="myBtn">click me!</button>
  </div>
  <script src="1.js"></script>
</body>
</html>

 

 

 

☑️ 실행결과 

 

 

 

type : 발생한 이벤트의 타입을 담고 있다

target: 이벤트가 발생한 그 해당 요소를 담고 있다

 

 

이벤트 객체 프로퍼티

 

 

1. 공통 프로퍼티

아래의 프로퍼티들은 이벤트 타입과 상관없이 모든 이벤트 객체들이 공통적으로 가지고 있는 프로퍼티

 

type 이벤트 이름 ('click', 'mouseup', 'keydown' 등)
target 이벤트가 발생한 요소
currentTarget 이벤트 핸들러가 등록된 요소
timeStamp 이벤트 발생 시각(페이지가 로드된 이후부터 경과한 밀리초)
bubbles 버블링 단계인지를 판단하는 값

 

 

 

2. 마우스 이벤트

마우스와 관련된 이벤트의 경우에는 아래와 같은 이벤트 객체의 프로퍼티들을 가지고 있다.

 

button 누른 마우스의 버튼 (0: 왼쪽, 1: 가운데(휠), 2: 오른쪽)
clientX, clientY 마우스 커서의 브라우저 표시 영역에서의 위치
pageX, pageY 마우스 커서의 문서 영역에서의 위치
offsetX, offsetY 마우스 커서의 이벤트 발생한 요소에서의 위치
screenX, screenY 마우스 커서의 모니터 화면 영역에서의 위치
altKey 이벤트가 발생할 때 alt키를 눌렀는지
ctrlKey 이벤트가 발생할 때 ctrl키를 눌렀는지
shiftKey 이벤트가 발생할 때 shift키를 눌렀는지
metaKey 이벤트가 발생할 때 meta키를 눌렀는지 (window는 window키, mac은 cmd키)

 

 

3. 키보드 이벤트

키보드와 관련된 이벤트의 경우에는 아래와 같은 이벤트 객체의 프로퍼티들을 가지고 있다.

 

key 누른 키가 가지고 있는 값
code 누른 키의 물리적인 위치
altKey 이벤트가 발생할 때 alt키를 눌렀는지
ctrlKey 이벤트가 발생할 때 ctrl키를 눌렀는지
shiftKey 이벤트가 발생할 때 shift키를 눌렀는지
metaKey 이벤트가 발생할 때 meta키를 눌렀는지 (window는 window키, mac은 cmd키)

 

 

 


 

 

 

이벤트 버블링

 

 

이벤트 버블링

어떤 하나의 요소에 이벤트가 발생하면 이 요소에 할당된 이벤트 핸들러가 동작하고 끝이 아니라 같은 타입의 이벤트 한에서 부모 이벤트 핸들러도 동작하게 된다

 

 

💡이벤트 버블링이 일어나도 이벤트 객체의 target 프로퍼티는 변하지 않고 처음 이벤트가 발생한 시작점을 담고 있다

 

 

이벤트 핸들러가 등록된 요소에 접근하고 싶을 때 currentTarget를 사용한다

 

 

 

버블링을 멈추는 방법

이벤트 객체에 stopPropagation 메소드를 활용하면 된다

 

 

// 이벤트 버블링 (Event Bubbling)
const content = document.querySelector('#content');
const title = document.querySelector('#title');
const list = document.querySelector('#list');
const items = document.querySelectorAll('.item');

content.addEventListener('click', function(e) {
  console.log('content Event');
  console.log(e.currentTarget);
});

title.addEventListener('click', function(e) {
  console.log('title Event');
  console.log(e.currentTarget);
});

list.addEventListener('click', function(e) {
  console.log('list Event');
  console.log(e.currentTarget);
});

for (let item of items) {
  item.addEventListener('click', function(e) {
    console.log('item Event');
    console.log(e.currentTarget);
		e.stopPropagation();
  });
}

 

 

버블링을 막아버리면 모든 부모 요소의 입장에서 아이템 영역만큼의 이벤트를 발생시킬 범위가 사라져버리기 때문에 사용하지 않는 것이 좋다

 

이벤트 버블링에 의해서 이벤트는 여기서 끝나는 것이 아니라 부모 요소로 이벤트가 계속 전파된다 

 

 

캡쳐링

 

 

표준 DOM 이벤트 에서 정의한 이벤트 흐름에는 3가지 단계

  1. 캡처링 단계: 이벤트가 하위 요소로 전파되는 단계
  2. 타깃 단계: 이벤트가 실제 타깃 요소에 전달되는 단계 (가장 처음 이벤트 핸들러가 동작하게 되는 순간)
  3. 버블링 단계: 이벤트가 상위 요소로 전파되는 단계

 

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8">
    <title>JS with Codeit</title>
  </head>
  <body>
    <div id="content">
      <h1 id="title">오늘 할 일</h1>
      <ol id="list">
        <li class="item">자바스크립트 공부</li>
        <li class="item">독서</li>
      </ol>
    </div>
    <script src="index.js"></script>
  </body>
</html>

 

자바스크립트 공부를 클릭한다면, 버블링은 li태그 부터, ol태그, div태그, body태그, html태그, document, window 객체로 이벤트가 전파된다

 

 

캡쳐링이벤트가 발생하면 가장 먼저, 그리고 버블링의 반대 방향으로 진행되는 이벤트 전파 방식

 

이벤트가 발생하면 가장 먼저 window 객체에서부터 target 까지 이벤트 전파가 일어난다 (캡쳐링 단계)

그리고 나서 타깃에 도달하면 타깃에 등록된 이벤트 핸들러가 동작한다 (타깃 단계)

이후 다시 window 객체로 이벤트가 전파된다. (버블링 단계)

 

 

 

이벤트 위임

 

 

// 이벤트 위임 (Event Delegation)
const list = document.querySelector('#list');
list.addEventListener('click', function(e) {
	// if (e.target.tagName === 'LI')
	if (e.target.classList.contains('item')) {
		e.target.classList.toggle('done');
	}
});// 부모요소의 리스트에 이벤트 핸들러를 하나만 등록해도 모든 자식 요소의
//이벤트를 다룰 수 있게 된다 

const li = document.createElement('li');
li.classList.add('item');
li.textContent = '일기 쓰기';
list.append(li);
li.addEventListener('click', function(e) {
  e.stopPropagation(); //자식요소 중에서 버블링을 막는 이벤트가 있을 경우에는 
  //버블링이 막혀버린다 
});

 

 

추가된 요소에도 이벤트 핸들러를 새로 등록하지 않고 사용할 수 있게하는 방법

→ 이벤트 위임 (이벤트 버블링을 활용한다)

 

자식 요소에서 다루는 이벤트를 부모 요소에 위임한다

→ 따라서 원하는 곳에서만 이벤트가 일어나게 하려면 다시 조작해줘야함

 

 

 

브라우저의 기본 동작

 

브라우저가 기본으로 가지고 있는 동작을 제어하는 방법

→ event객체의 preventDefault 메소드를 활용한다

 

 

// 브라우저의 기본 동작
const link = document.querySelector('#link');
const checkbox = document.querySelector('#checkbox');
const input = document.querySelector('#input');
const text = document.querySelector('#text');

link.addEventListener('click', function(e) {
	e.preventDefault();
	alert('지금은 이동할 수 없습니다.');
});

input.addEventListener('keydown', function(e) {
	if (!checkbox.checked) {//체크하지 않았다면 
		e.preventDefault();
		alert('체크박스를 먼저 체크해 주세요.');
	}
});

document.addEventListener('contextmenu', function(e) {//문서 전체 우클릭방지 
	e.preventDefault();
	alert('마우스 오른쪽 클릭은 사용할 수 없습니다.');
});

 

 

 


 

 

✍️요약 정리

 

1. 이벤트 핸들러 등록하기

HTML의 속성이나 DOM 프로퍼티를 활용해 이벤트를 등록하는 방법 외에 Element.addEventListener('type', 'handler')를 통해서 이벤트 핸들러를 등록할 수 있다.

 



2. 이벤트 핸들러 삭제하기

`addEventListener` 메소드를 활용해서 이벤트 핸들러를 등록했다면, Element.removeEventListner('type', 'handler')를 통해서 이벤트 핸들러를 삭제할 수 있다.

3. 이벤트 객체 (Event Object)

이벤트가 발생하면 이벤트 핸들러의 첫 번째 파라미터에는 자동으로 이벤트 객체가 전달된다.
이벤트 객체는 이벤트 종류마다 가지고 있는 프로퍼티가 다르며, 이벤트에 대한 유용한 정보들을 프로퍼티로 가지고 있다.

4. 이벤트 버블링 (Event Bubbling)

이벤트는 전파가 된다.

 

어떤 요소에서 이벤트가 발생하면 해당 요소에 등록된 이벤트 핸들러가 동작하는 것뿐만 아니라 부모 요소로 이벤트가 계속해서 전파되면서 각 요소에도 등록된 이벤트 핸들러가 있다면 차례로 이벤트 핸들러가 동작한다.

자식 요소에서 부모 요소로 이벤트가 전파되는 것을 이벤트 버블링(Event Bubbling)이라고 부른다


5. 이벤트 위임 (Event Delegation)

버블링 개념을 활용하면 훨씬 효과적인 이벤트 관리를 할 수 있다. 예를 들어 자식 요소 각각에 이벤트 핸들러를 하나씩 등록할 필요 없이 부모 요소에서 한 번에 자식 요소들에 발생한 이벤트를 관리할 수도 있다.

이렇게 이벤트를 다루는 방식을 자식 요소의 이벤트를 부모 요소에 위임한다고 해서 이벤트 위임(Event Delegation)이라고 부른다. 이벤트 위임을 잘 활용하면 훨씬 더 효율적으로 이벤트를 다룰 수 있다.

6. 브라우저의 기본 동작

브라우저에는 각 태그별 혹은 상황별로 기본적으로 약속된 동작들이 있다. 예를 들어 마우스 오른쪽 버튼을 클릭하면 상황에 맞는 메뉴 창이 뜬다거나, `input` 태그에 커서를 두고 키보드 키를 누르면 해당 값이 입력되는 것 등등 

 

이러한 동작들을 막고 싶다면 이벤트 객체의 `preventDefault` 메소드를 통해 막을 수가 있다.

 

728x90