Study/Javascript

Javascript_08: 이벤트(event)

devyoseph 2021. 9. 24. 03:39
element.addEventListener(event, handler);

onclick 이벤트는 새로운 이벤트를 할당할 때 덮어씌워지는 단점이 있다

const btn = document.querySelector('#btn1');

btn.onclick = function(){
	console.log("Hello");
}
btn.onclick = function(){
    console.log("Bye");
}//btn버튼의 결과값은 Bye가 나온다

 

이런 문제를 줄이기 위해 addEventListener를 사용한다

function event1(){
	console.log("Hello");
}
function event2(){
	console.log("Bye");
}

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

*event1과 event2가 모두 실행되며 덮어쓰기의 문제 발생X

이벤트를 제거할 때도 간편하다

element.removeEventListener(event, handler);
function event1(){
	console.log("Hello");
}
function event2(){
	console.log("Bye");
}

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

btn.removeEventListener('click',event1);
이벤트의 등록 / 삭제
등록 elem.addEventListener(event,handler);
삭제 elem.removeEventListener(event,handler);
*handler에 입력하는 함수이름에 (소괄호)를 쓰지 않도록 주의한다

 


 

이벤트 종류

마우스 이벤트 mousedown 마우스 버튼을 누르는 순간
mouseup 마우스 버튼을 눌렀다 떼는 순간
click 왼쪽 버튼을 클릭한 순간
dblclick 왼쪽 버튼을 빠르게 두 번 클릭한 순간
contextmenu 오른쪽 버튼을 클릭한 순간
mousemove 마우스를 움직이는 순간
mouseover 마우스 포인터가 요소 위로 올라온 순간
mouseout 마우스 포인터가 요소에서 벗어나는 순간
mouseenter 마우스 포인터가 요소 위로 올라온 순간(버블링X) 
mouseleave 마우스 포인터가 요소에서 벗어난 순간(버블링X)
포커스 이벤트 focusin 요소에 포커스되는 순간
focusout 요소에 포커스가 나간 순간
focus 요소에 포커스 되는 순간(버블링X)
blur 요소에 포커스가 나간 순간(버블링X)
입력
이벤트
change 입력된 값이 바뀌는 순간
input 값이 입력되는 순간
select 입력 양식의 하나가 선택되는 순간
submit 폼을 전송하는 순간
스크롤 이벤트 scroll 스크롤하는 순간
윈도우 이벤트 resize 윈도우 사이즈를 움직일 때

*이벤트 버블링 설명은 아래에 있다

 

event 객체를 활용해 반응성을 높힐 수 있다

이벤트를 작동시키는 방법도 중요하지만 사용자가 어떤 값을 입력하는지, 마우스 좌표는 어떻게 되는지 등 정보를 활용해 이벤트를 구체화할 수 있다. 이것은 이벤트 객체를 사용해 구체화할 수 있다

function handler명(event){ }
const myBtn = document.querySelector('#btn');

function event1(event){
	console.log(event);
//이벤트 객체를 추적해보자
}
btn.addEventListener('click', event1);

 

event.프로퍼티

이벤트 객체의 프로퍼티에 접근해서 이벤트를 좀 더 세밀하게 다룰 수 있다. 이것을 위해선 이벤트 프로퍼티를 알아야 한다.

이벤트 프로퍼티
공통 프로퍼티(모든 이벤트 객체 적용) 마우스 이벤트 키보드 이벤트
type 이벤트 이름 button 마우스 클릭한 부분 key 누른 키의 값
target 이벤트 발생 요소 clientX, clientY 브라우저 내 위치 code 누른 키의 물리 위치
currentTarget 이벤트 핸들러 요소 pageX, pageY 문서영역 위치 altKey alt키를 눌렀는지
timeStamp 이벤트 발생 시각 offsetX, offsetY 요소 위치 ctrlKey ctrl키를 눌렀는지
bubbles 버블링 단계 판별 screenX, screenY 모니터 내 위치 shiftKey shift키를 눌렀는지
  altKey alt키를 눌렀는지 metaKey meta키를 눌렀는지
ctrlKey ctrl키를 눌렀는지  
preventDefault(); 이벤트를 중단 shiftKey shift키를 눌렀는지
stopPropagation 버블링을 멈춤 metaKey meta키를 눌렀는지

*metaKey: window는 윈도우키 / Mac은 cmd키

*e.stopPropagation은 공간을 낭비하므로 잘 쓰지 않는다

 

*이벤트 버블링(bubbling)

어떤 하나의 이벤트를 실행하면 같은 타입의 부모요소 이벤트도 같이 동작한다. 거꾸로 올라가는 모습을 물 속 방울이 올라가는 모양(bubble)에 비유했다. 최상단 window 객체를 만날 때까지 연쇄적으로 작용한다

이벤트 버블링을 이용할 수도, 추적할 수 있다

*버블링의 이용 = 이벤트 위임

추적

function event1(e){
	console.log(e.target);
}

*event속성의 target은 어느 위치에서나 최초 실행된 요소를 반환한다

현 위치 반환

function event1(e){
	console.log(e.currentTarget);
}

*event속성의 currentTarget은 현재 요소를 반환한다

 

*이벤트 캡쳐링(capturing)

버블링의 반대개념. 어떤 하나의 이벤트를 실행하면 같은 타입의 자식요소 이벤트도 같이 동작한다. 최상단 window 객체에서 시작해 target 요소를 만날 때까지 연쇄적으로 작용한다. target에 도달하면 버블링도 발생하게 된다

캡쳐링 사용법

element.addEventListener(event, handler, true) 세번째 요소에서 true를 사용한다 

*여기서 true는 {capture:true}의 축약형이다

*javascript.info 참조

<!doctype html>
<body>
<style>
  body * {
    margin: 10px;
    border: 1px solid blue;
  }
</style>

<form>FORM
  <div>DIV
    <p>P</p>
  </div>
</form>

<script>
  for(let elem of document.querySelectorAll('*')) {
    elem.addEventListener("click", e => alert(`캡쳐링: ${elem.tagName}`), true);
    elem.addEventListener("click", e => alert(`버블링: ${elem.tagName}`));
  }
</script>
</body>

 

이벤트 위임(Delegation)-버블링의 연장선

<ul> 안 <li>로 이루어진 리스트에 이벤트를 등록했다고 한다면 새로운 목록을 추가하고 싶을 때 이벤트를 바로 적용할 수 없는지 고민하게 된다. 버블링을 이용해 바로 상위의 부모요소에 이벤트를 할당하면 된다

부모요소.addEventListener(event, handler); 

이렇게 설정하면 하위에 <li>를 추가해도 버블링으로 인해 부모요소의 이벤트가 실행된다

그러나 부모요소가 이벤트에 포함되기 때문에 그것을 제한해주어야한다

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');
	}
    //target과 classList.contains를 활용
});

기억할 것

이벤트의 등록 / 삭제
등록 elem.addEventListener(event,handler);
삭제 elem.removeEventListener(event,handler);
*handler에 입력하는 함수이름에 (소괄호)를 쓰지 않도록 주의한다