티스토리 뷰

JAVASCRIPT/개념정리

[Javascript] 이벤트 처리

jeongah story 2020. 7. 5. 17:50

[모던자바스크립트]15장 이벤트 처리

 

15.1 이벤트 처리기를 등록하는 방법

: 이벤트가 발생했을 때 실행되는 함수를 이벤트 처리기 또는 이벤트 리스너라고 합니다.

 

등록방법

1. HTML요소의 이벤트 처리기 속성에 설정하는 방법 :

<input type="button" onclick="changeColor();">  



1-1. 이벤트 처리기의 문제점

* HTML 문서를 읽어 들일 때 이벤트 처리기도 함께 설정하기 때문에 설정하기 쉽습니다.

* HTML과 자바스크립트 프로그램이 뒤섞여 프로그램의 가독성이 떨어집니다.
결과적으로 프로그램의 유지 보수성이 떨어집니다.

* 특정 요소의 특정 이벤트에 대해서 이벤트 처리기를 단 하나만 등록할 수 있습니다. 그 요소에 똑같은 이벤트 
처리하는 이벤트 처리기를 등록하면 나중에 등록한 함수가 이전에 등록한 함수를 덮어씁니다. 
일반적으로 HTML문서 하나는 여러명의 개발자가 작성한 자바스크립트 파일과 
라이브러리 위에서 동작합니다. 이때 두 개 이상의 파일이 같은 요소에 
같은 이벤트 처리하는 함수를 등록해 버리면 이전에 등록한 이벤트 처리기가 무효로 처리됩니다. 
따라서 해당 자바스크립트 파일이나 라이브러리가 제대로 동작하지 않을 수 있습니다.
2. DOM요소 객체의 이벤트 처리기 프로퍼티에 설정하는 방법 :

var btn=document.getElementById("button");
btn.onclick=changeColor();


2-1. 이벤트 처리기의 문제점 
<DOM 요소 객체의 이벤트 처리기 프로퍼티에 설정한 경우>

* HTML과 자바스크립트 프로그램을 분리해서 작성할 수 있습니다.
즉, HTML과 자바스크립트의 연결을 느슨하게 하는 '겸손한 자바스크립트'를 구한할 수 있습니다.
결과적으로 프로그램의 유지 보수성을 높일 수 있습니다.

* 특정 요소의 특정 이벤트에 대해서 이벤트 처리기를 단 하나만 등록할 수 있습니다.
이는 1번과 같은 단점입니다.
3. addEventListener메서드를 사용하는 방법:

var btn = document.getElementById("button");
btn.addEventListener("click", changeColor, false);

 

 

15.2 이벤트 리스너를 등록하고 삭제하는 방법

(등록 :  addEventListener  / 삭제 : removeEventListener)

 

15.2.1 addEventListener메서드로 이벤트 리스너 등록하기

: addEventListenr로 등록한 함수는 이벤트 리스너라는 이름으로 부릅니다.

target.addEventListener(type, listener, useCapture);

<구성 요소의 의미>
* target     :   이벤트 리스너를 등록할 DOM노드
* type       :   이벤트 유형을 뜻하는 문자열("click", "mouseUp" 등)
* listener   :   이벤트가 발생했을 때 처리를 담당하는 콜백 함수의 참조
* useCapture :   이벤트 단계 (true: 캡처링 단계 / false : 버블링 단계(생략했을 때의 기본값)


<addEventListener 장점>
* 같은 요소의 같은 이벤트에 이벤트 리스너를 여러개 등록할 수 있다.
* 버블링 단계는 물론 캡처링 단계에서도 활용할 수 있다.
반면에 DOM요소 객체에 직접 등록한 이벤트 처리기는 버블링 단계의 이벤트만 캡처할 수 있다.
* removeEventListener, stopPropagation, preventDefault를 활용하여 
이벤트 전파를 정밀하게 제어할 수 있다.
* HTML요소를 포함한 모든 DOM노드에 이벤트 리스너를 등록할 수있다.

 

See the Pen [Javascript]이벤트 처리 - addEventListener메서드 by jeongahlee (@jeongahlee) on CodePen.

 

* 앞 코드에서 이벤트 리스너 함수가 받은 인수를 e는 이벤트 객체 이며, e.currentTarget은 클릭한 요소를 참조하는 요소 객체입니다.

* 이벤트 유형을 뜻하는 문자열이 "onclick" 

* useCapture값을 false로 지정 > false는 이벤트의 전파 단계가 버블링 단계일 때 그 이벤트를 캡쳐하라는 뜻입니다.

(보통 false를 지정합니다.)

 

15.2.3 removeEventListener 메소드로 이벤트 리스너 삭제하기

target.removeEventListener(type, listener, useCapture);

window.onload= function(){
	var el = document.getElementById("button");
    el.addEventListener("click", function(e){
    	console.log("hello");
        el.removeEventListener("click", arguments.callee, false);
    }, false);
}

 

 

 

15.3 이벤트 객체 

: 이벤트 리스너 함수의 인수인 이벤트 객체

 

15.3.1  이벤트 객체

: 해당 이벤트의 다양한 정보를 저장한 프로퍼티와 이벤트의 흐름을 제어하는 메서드를 가지고 있습니다.

 

function changeColor(e){
	e.currentTarget.style.backgroundColor="red";
}

여기서 인수 e가 이벤트 객체 입니다.
이것은 함수 안에서만 유효한 인자이므로 그 어떤 식별자도 이벤트 객체의 이름으로 사용할 수 있습니다.
이것을 명시하기 위해 e 또는 event를 사용하는 것이 관례입니다.

 

<이벤트 객체의 공통 프로퍼티>

프로퍼티 값의 타입 설명
type 문자열 이벤트 이름("click", "mausedown", "keydown" 등)
target 요소 객체 이벤트가 발생한 요소
currentTarget 요소 객체 처리를 담당한 이벤트 리스너가 등록된 요소 객체
eventPhase 정수 이벤트 전파 단계 ( 1:캡처링, 2:타깃, 3:버블링)
timeStamp 정수 이벤트 발생 시각(1000/1/1,00:00:00부터 경과한 밀리초)
bubbles 논리값 버블링 단계인지 뜻하는 값
cancleable 논리값 preventDefault()로 기본 이벤트를 취소할 수 있는지를 뜻하는 값
defaultPrevented 논리값 preventDefault()로 기본 작업이 취소되었는지를 뜻하는 값
isTrusted 논리값 해당 이벤트가 사용자의 액션에 의해 생성되었는지를 뜻하는 값

 

 

<마우스 이벤트 객체>

프로퍼티 값의 타입 설명
screenX, screenY 정수 클릭한 위치의 화면 좌표(컴퓨터 화면의 왼쪽 위 꼭짓점이 원점)
clientX, clientY 정수 클릭한 위치의 윈도우 좌표(표시 영역의 왼쪽 위 꼭짓점이 원점)
pageX, pageY 정수 클릭한 위치의 문서 좌표(문서의 왼쪽 위 꼭짓점이 원점)
offseetX, offsetY 정수 이벤트가 발생한 요소의 상대 좌표(요소의 왼쪽 위 꼭짓점이 원점)
altKey 논리값 alt가 눌렀는지를 뜻하는 논리값
ctrlKey 논리값 ctrl가 눌렀는지를 뜻하는 논리값
shiftKey 논리값 shift가 눌렀는지를 뜻하는 논리값
detail 정수 이벤트의 자세한 정보: 마우스 이벤트의 경우에는 클릭한 횟수
button 정수 눌린 마우스의 버튼(0:왼쪽버튼,1:휠 버튼,2:오른쪽 버튼)
relatedTarget 객체 mouse 이벤트에서는 마우스가 떠난 노드
mouseout 이벤트에서는 마우스가 들어온 노드

더보기
* 이미지(img요소)를 드래그해서 옮길 때 주의 할 점
src속성을 지정한 img 요소는 기번족으로 드래그할 수 있도록 만들어져 있습니다.
따라서 img요소를 마우스로 드래그해서 옮길 때는 주의를 기울여야 합니다. 
사용자가 mouseup과 mousemove이벤트의 이벤트 리스너를 등록해서 마우스로 이동시키려고 하면 
웹 브라우저가 그 이벤트를 취소해 버리므로 드래그해서 옮길 수 없습니다.
이를 방지하려면 mousedown이벤트 리스너 안에서 이벤트 객체의 preventDefault 메서드를 실행해야 합니다.

 

 

15.4 이벤트의 전파 

: 이벤트가 HTML요소에서 발생했을 때 이벤트가 전파되는 과정

: Window 객체나 XMLhttpRequest 객체처럼 단독으로 존재하는 객체에서 이벤트가 발생하면 웹 브라우저는 해당 객체에 등록된 이벤트 처리기를 호출합니다. 그러나 이벤트가 HTML요소에서 발생하면 그 요소는 물론 그 요소의 모든 조상요소에 이벤트를 전파합니다.

겨로가적으로 그 모든 요소에 등록된 이벤트 처리기가 호출됩니다. 

 

15.4.1 이벤트 단계

: 이벤트가 발생한 요소는 이벤트 타깃, 이벤트를 발생시키는 것을 가리켜 이벤트를 발사(Fire)라고 표현합니다.

 

1. 캡처링 단계

: 이벤트가 Window객체에서 출발해서 DOM트리를 타고 이벤트 타깃까지 전파됩니다.

등록된 이벤트 리스너는 이벤트가 발생한 요소에 등록된 이벤트 처리기나 이벤트 리스너보다 먼저 실행됩니다.

이 단계는 이벤트 타깃이 이벤트를 수신하기 전에 이벤트를 빼돌리는(캡처하는) 단계라는 뜻에서 캡처링 단계라는 이름이 붙었습니다.

 

2. 타깃 단계

: 이벤트가 타깃에 전파되는 단계입니다.  

이벤트 타깃에 등록된 이벤트 처리기나 이벤트리스너는 이 시점에 실행됩니다.

 

3. 버블링 단계

: 이벤트가 이벤트 타깃에서 출발해서 DOM트리를 타고 Window객체에 전파됩니다.

이 단계에 반응하도록 등록된 이벤트 리스너는 이벤트가 발생한 요소에 등록된 이벤트 처리기나 이벤트 리스너 다음에 실행됩니다.

이 단계는 이벤트가 마치 거품(버블)이 올라오는 것처럼 DOM트리 아래에서부터 위로 올라온다는 뜻에서 버블링 단계라는 이름이 붙었습니다. 단,

 

focus와 blur 이벤트는 그 요소에만 필요한 이벤트이브로 버블링이 발생하지 않습니다.

 

만약 이벤트 처리기를 등록했다면 이벤트 처리기는 타깃 단계와 버블링 단계에 모두 실행됩니다.

 

이벤트 리스너(이벤트 리스너는 실행할 단계를 선택할 수 있습니다.)

useCapture가 true이번 타깃 단계와 캡처링 단계일 때만 실행됩니다.

useCaptur가 false이면 타깃 단계와 버블링 단계일 때만 실행됩니다.

 

같은 요소 같은이벤트, 같은 단계에 반응하게끔 등록된 이벤트 처리기와 이벤트 리스너는 등록된 순서에 따라 차례대로 실행됩니다.

또한, 같은 요소의 같은 이벤트의 캡처링 단계와 버블링단계 모두 이벤트 리스너를 등록할 수 있습니다.

 

<div id="outer">
	outer
    <div id="inner1">inner1</div>
    <div id="inner2">inner2</div>
</div>

가정 :  inner2를 클릭해서 이벤트가 발생 

<script>
	window.onload = function(){
    	var outer = document.getElementById("outer");
        var inner2 = document.getElementById("inner2");
        outer.addEventListener("clilck", function(e){
        	console.log("outer bubbleing");
        }, false); //터갓단계와 버블링 단계일때만 실행
        outer.addEventListener("clilck", function(e){
        	console.log("outer capturing");
        }, true);  //타깃 단계와 캡처링 단계일때만 실행
        inner2.addEventListener("clilck", function(e){
        	console.log("inner2 bubbleing");
        }, false); //터갓단계와 버블링 단계일때만 실행
    }
</script>


//결과 
outer captureing > inner2 bubbling > outerbubbling

캡처링단계>타깃단계>버블링단계

이처럼 이벤트 리스너는 이벤트가 전파되는 순서에 따라 차례대로 실행됩니다.

 

 

15.4.2 이벤트의 전파

:자식 요소에서 발생한 이벤트는 부모 요소에도 전파됩니다.

이럴 때는 이벤트 전파를 취소해서 부모 요소가 이벤트 처리를 하지 않도록 만들 수 있습니다.

또한 이벤트가 발생했을 때 실행되는 웹 브라우저의 기본 동작도 취소할 수 있습니다.

 

 

See the Pen [Javascript] 이벤트의 전파 by jeongahlee (@jeongahlee) on CodePen.

 

15.5 이벤트 리스너 안의 this

: 이벤트 리스너 안의 this 값은 '함수를 호출할 때 그 함수가 속해 있던 객체의 참조' 입니다.

 

15.5.2 this가 원하는 객체를 가리키도록 설정하는 방법

 

See the Pen [Javascript] this event by jeongahlee (@jeongahlee) on CodePen.

 

 

15.6 이벤트 리스너에 추가적인 정보를 넘기는 방법

:addEventListener의 두번 째 인수인 이벤트 리스너는 이벤트 객체를 인수로 받습니다.  이벤트 리스너에 이벤트 객체 외의 추가적인 정보를 전달하는 문제를 해결하는 방법

 

15.6.1 익명 함수 안에서 실행하기

 

See the Pen [Javascript] 이벤트 리스너에 추가적인 정보를 넘기는 방법 by jeongahlee (@jeongahlee) on CodePen.

댓글
© 2018 eh2world