관리 메뉴

FU11M00N

[ JavaScript ] JS 이벤트 ( inline , 프로퍼티 리스너 , addEventListener) 본문

SUA 정보보안/JavaScript

[ JavaScript ] JS 이벤트 ( inline , 프로퍼티 리스너 , addEventListener)

호IT 2021. 2. 10. 01:35

이미지 출처 :    https://www.inflearn.com/course/javascript-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EA%B0%95%EC%A2%8C#

 

생활코딩의 이고잉 님의 강의를 기반으로 개인 공부용으로 정리한 포스팅입니다.

 

 

 

 


 

 

 

 

- 이벤트(Event)란

 

 

이벤트(event)는 어떤 사건을 의미합니다.

 

브라우저에서의 사건이란 사용자가 클릭을 했을 '때', 스크롤을 했을 '때', 필드의 내용을 바꾸었을 '때'와 같은 것을 뜻합니다.

 

<!DOCTYPE html>
<html>
<body>
    <input type="button" onclick="alert(window.location)" value="alert(window.href)" />
    <input type="button" onclick="window.open('bom.html')" value="window.open('bom.html')" />
</body>
</html>

 

 

onclick 속성의 자바스크립트 코드(alert(window.location))는 사용자가 이 버튼을 클릭 했을 '때' 실행됩니다.

 

JS 개발자는 어떤 일이 발생했을 때 실행 되어야 하는 코드를 등록합니다.

 

그리고 브라우저는 그 일이 발생했을 때 등록된 코드를 실행하게 됩니다.

 

 

 

이러한 방식을 이벤트 프로그래밍이라고 합니다.

 

 

 

 

- event target

 

 

target은 이벤트가 일어날 객체를 의미합니다.

 

타겟은 버튼 태그에 대한 객체가 됩니다.

 

 

<input type="button" onclick="alert(window.location)" value="alert(window.href)" />

 

 

 

- event type

 

이벤트의 종류를 의미합니다.

 

위의 예제에서는 click이 이벤트 타입입니다.

그 외에도 scroll은 사용자가 스크롤을 움직였다는 이벤트이고,

mousemove는 마우스가 움직였을 때 발생하는 이벤트입니다.

 

 

이벤트의 종류는 약속되어 있습니다. 

 

 

 

 

- event handler

 

이벤트가 발생했을 때 동작하는 코드를 의미합니다.

 

alert(window.location)

위의 예제 alert(window.location)이 event handler 입니다.

 

 

 

이벤트 프로그래밍을 하기 위해서는 이벤트의 대상에 이벤트 핸들러를 등록해줘야 합니다.

 

 

 

 

 

 

 

 

 

웹브라우저에서는 크게 3가지 종류의 등록방법을 제공합니다.

 

- inline 방식

 

인라인 방식은 이벤트를 이벤트 대상의 태그 속성으로 지정하는 것입니다.

다음은 버튼을 클릭했을 때 Hello world를 경고창으로 출력하는 예시입니다.

 

 

<input type="button" onclick="alert('Hello world');" value="button" />

 

이벤트가 발생한 대상을 필요로 하는 경우에 this를 통해서 참조할 수 있습니다.

 

 

 

<!--자기 자신을 참조하는 불편한 방법-->
<input type="button" id="target" onclick="alert('Hello world, '+document.getElementById('target').value);" value="button" />
<!--this를 통해서 간편하게 참조할 수 있다-->
<input type="button" onclick="alert('Hello world, '+this.value);" value="button" />

 

 

인라인 방식은 태그에 이벤트가 포함되기 때문에 이벤트의 소재를 파악하는 것이 편리합니다.

 

하지만 정보인 HTML과 제어인 JavaScript가 혼재된 형태이기 때문에 바람직한 방법이라고 할수는 없겠죠. 

 

그렇기에 프로퍼티 리스너 방식이 존재합니다.

 

- 프로퍼티 리스너 방식

 

 

프로퍼티 리스너 방식은 이벤트 대상에 해당하는 객체의 프로퍼티로 이벤트를 등록하는 방식입니다.

 

인라인 방식에 비해서 HTML과 JavaScript를 분리할 수 있다는 점에서 선호되는 방식입니다.

 

하지만 "addEventListener" 방식을 더 추천합니다. (뒤에 내용있음.)

 

 

 

<input type="button" id="target" value="button" />
<script>
    var t = document.getElementById('target');
    t.onclick = function(){
        alert('Hello world');
    }
</script>

프로퍼티 리스너 방식 코드

 

 엘리먼트의 onclick 속성에 이벤트 핸들러를 지정하는 코드입니다.

 

 

- 이벤트 객체

 

 

이벤트가 실행된 맥락의 정보가 필요할 때는 이벤트 객체를 사용합니다.

 

이벤트 객체는 이벤트가 실행될 때 이벤트 핸들러의 인자로 전달됩니다.

 

하지만

 

ie8 이하 버전에서는 이벤트 객체를 핸들러의 인자가 아니라 전역객체의 event 프로퍼티로 제공하기 때문에 문제가 발생합니다.

 

 

 

 

또한 ie8 이하 버전에서는 target 프로퍼티도 지원하지 않습니다.

 

 

<body>
    <input type="button" id="target" value="button" />
<script>
    var t = document.getElementById('target');
    t.onclick = function(event){
        alert('Hello world, '+event.target.value)
    }
</script>

 

 

alert 구문에는 인자로 받게되는 event 객체에 target을 사용하여 이벤트가 실행된 정보를 얻어옵니다.

 

 

 

<input type="button" id="target" value="button" />
<script>
    var t = document.getElementById('target');
    t.onclick = function(event){
        var event = event || window.event;
        var target = event.target || event.srcElement;
        alert('Hello world, '+target.value)
    }
</script>

위의 예시는 ie8 이하 버전과의 크로스 브라우저 이슈를 해결하기 위한 코드입니다.

 

var event = event || window.event;

 

위의 구문이 어색하게 느껴질 수도 있는데, 이 구문은

 

event 가 존재하면 var event = event 를 이행하고, 존재하지 않는다면 var event = window.event 를 이행하라는 의미입니다.

 

 

 

 

 

- addEventListener 방식

 

 

addEventListener은 이벤트를 등록하는 가장 권장되는 방식입니다.

 

이 방식을 이용하면 여러개의 이벤트 핸들러를 등록할 수 있습니다.

 

 

 

<input type="button" id="target" value="button" />
<script>
    var t = document.getElementById('target');
    t.addEventListener('click', function(event){
        alert('Hello world, '+event.target.value);
    });
</script>

 

 

이 방식은 ie8이하에서는 호환이 안됩니다.

 

 

 

 

ie에서는 attachEvent 메소드를 따로 사용해야만 합니다. 

 

 

var t = document.getElementById('target');
if(t.addEventListener){
    t.addEventListener('click', function(event){
        alert('Hello world, '+event.target.value);
    }); 
} else if(t.attachEvent){
    t.attachEvent('onclick', function(event){
        alert('Hello world, '+event.target.value);
    })
}

위의 처럼 코드를 작성하면 크로스 브라우저 이슈를 해결할 수 있습니다.

 

 

 

 

 

 

 

이 방식의 중요한 장점은,

하나의 이벤트 대상에 복수의 동일 이벤트 타입 리스너를 등록할 수 있다는 점입니다. 

 

 

 

 

<input type="button" id="target" value="button" />
<script>
    var t = document.getElementById('target');
    t.addEventListener('click', function(event){
        alert(1);
    });
    t.addEventListener('click', function(event){
        alert(2);
    });
</script>

 

 

만약 인라인 방식이나 프로퍼티 리스너 방식을 사용하면, 하나의 이벤트 대상에는 하나의 동일 이벤트 타입 리스너만 등록 가능합니다.

 

 

<input type="button" id="target1" value="button1" />
<input type="button" id="target2" value="button2" />
<script>
    var t1 = document.getElementById('target1');
    var t2 = document.getElementById('target2');
    function btn_listener(event){
        switch(event.target.id){
            case 'target1':
                alert(1);
                break;
            case 'target2':
                alert(2);
                break;
        }
    }
    t1.addEventListener('click', btn_listener);
    t2.addEventListener('click', btn_listener);
</script>

하지만

이벤트 객체를 이용하면 복수의 엘리먼트에 하나의 리스너를 등록해서 사용하는 것도 가능합니다.

 

 

 

 

 

 

SUA 정보보안 멘토링에 참여하고 있습니다.

 

 

Comments