이벤트란 ?
어떠한 사건을 의미한다.
브라우저에서 사건이란 클릭, 스크롤을 올리거나 내리는 행위, 필드의 내용을 바꾸는 등의 행위 같은 것들을 의미한다.
정확히 말해서 클릭한 "순간", 스크롤 한 "순간", 필드의 내용을 바꾼 "순간" 등 행위를 한 순간순간이라고 보면 된다.
이러한 이벤트가 발생했을 때 어떠한 작업을 할 지 코드를 작성하는 것을
"이벤트 프로그래밍"
이라고 한다.
<input type="button" onclick="alert(1)" value="CLICK" />
위와 같은 단순한 HTML 코드가 있다.
CLICK 이라고 써져있는 버튼을 클릭하면 숫자 1을 표시하는 경고창이 뜬다.
이 때 CLICK 이라고 써져있는 버튼,
위 HTML 코드로 되어있는 button 타입의 input 태그를 이벤트 타겟(Event Target) 이라고 한다.
이벤트타겟은 이벤트가 발생하는 대상이다.
그리고 onclick="alert(1)" 은 클릭했을 "때" 1 경고창을 표시한다는 의미이다.
여기서 click이 이벤트타입이 된다.
마찬가지로,
<input type="text" onchange="alert(1)" />
텍스트타입의 input 태그에서 필드값을 변경하고 마우스를 다른곳에 클릭하여 변경이 일어났을 때,
1 경고창을 띄어주는 것이다.
여기선 change 가 이벤트타입이 된다.
필드가 바뀌었을 "때" 를 의미하는 것이다.
1) 인라인 방식
이벤트 프로그래밍을 하기 위해선 이벤트가 발생하는 대상에 이벤트를 등록? 설치? 해야 한다.
인라인 방식이란,
이벤트 대상의 태그 속성으로 지정하는 것이다.
지금까지 예제에서 계속 사용해왔던 onclick="" 로 해서 따옴표 안에 자바스크립트 내용을 넣은 것과 같은 방식이다.
여기서 잠깐 this 의 개념에 대해서 간단하게 집고 넘어간다.
함수 내에서 this를 사용한다는 것은 함수가 속해있는 객체를 의미하는 것이라고 보면 된다.
지금까지 정리했던 내용들을 기반으로 this를 설명하는 것은 무리이다.
그래서 그냥 여기서는 this가 자기 자신을 의미한다 정도로만 이해하면 된다.
<input type="button" id="a" onclick="alert('Hello, ' + document.getElementById('a').value)" value="test1" />
<input type="button" onclick="alert('Hello, ' + this.value)" value="test2" />
위와 같은 HTML 코드가 있다.
둘다 인라인 방식으로 이벤트가 일어날 button 태그 내의 onclick 속성에 자바스크립트 코드를 넣었다.
첫 번째 코드는,
클릭 이벤트 발생 시 Hello, 라는 문자와 id가 a인 엘리먼트를 찾아 그 엘리먼트의 value값을 붙혀 alert 해주는 것이다.
두 번째 코드는,
클릭 이벤트 발생 시 Hello, 라는 문자와 this를 이용하여 자기자신의 value값을 붙혀 alert 하는 것이다.
위 두 코드는 같은 기능을 하는 코드지만 this를 이용하면 훨씬 더 간편하게 사용할 수 있다.
차이점은,
<input type="button" id="a" onclick="console.log(document.getElementById('a').value)" value="test1" />
<input type="button" id="a" onclick="console.log(document.getElementById('a').value)" value="test2" />
value 값만 다르게 하여 같은 button 타입의 input 태그를 만들고 클릭할 때 console.log로 value값을 찍는 것이다.
getElementById는 해당하는 ID에 대해 하나의 엘리먼트만을 조회한다.
두 개의 버튼을 모두 클릭해도 value가 가장 처음에 나오는 test1만을 가리키는 것을 볼 수 있다.
반대로 this를 사용해보면,
<input type="button" onclick="console.log(this.value)" value="test1" />
<input type="button" onclick="console.log(this.value)" value="test2" />
자기 자신을 의미하기 때문에 각각의 값을 가져올 수 있고 코드를 관리하기가 수월해진다는 것이다.
인라인방식은,
장점과 단점이 존재한다.
태그에 직접 기술되어 있기 때문에 태그에 해당되는 이벤트가 무엇인지를 쉽게 찾을 수 있다는 것이 장점이 되고,
태그에 직접 기술되어 있다는 것이 단점이 된다.
?? 무슨말이냐면,,
기본적으로 HTML은 정보를 표현하기 위한 수단이다.
디자인은 css, 제어부문은 js로 분류하는 것이 좋은 html 코드의 요건이 된다고 볼 수 있기 때문에 정보에 해당하는 HTML에 혼재되어있는 코드는 HTML 정보의 가치를 저하시키는 요인으로 지목이 된다고 본다.
그리고 또 한가지는 태그 내에 속성명 부분에 직접 기술되기 때문에 복잡한 코드를 넣을 수 없다는 것이 단점이다.
2) 프로퍼티 리스너 방식
프로퍼티 리스너 방식은,
이벤트 대상에 해당하는 객체의 프로퍼티로 이벤트를 등록하는 방식이다.
코드로 확인해본다.
<input type="button" id="a" value="test" />
<script>
var b = document.getElementById("a");
b.onclick = function(){
console.log("test message");
}
</script>
계속해서 했던 예제와 같은 형식이다.
id가 a인 button 타입의 input 태그의 엘리먼트에 대한 객체를 변수 b에 담았다.
해당 엘리먼트 객체의 프로퍼티인 onclick 프로퍼티에 함수를 지정해주게 되면,
id가 a인 엘리먼트에 클릭이 일어났을 때 onclick 프로퍼티에 정의되어있는 메소드를 실행시켜주게 된다.
이 함수를 이벤트 핸들러 또는 이벤트 메소드 라고 한다.
다른 코드를 하나 더 확인해본다.
<input type="button" id="a" value="test" />
<script>
var b = document.getElementById("a");
b.onclick = function(a){
console.log("test message " + a.target.value);
}
</script>
function 에 a 라는 파라미터를 추가한 후 a.target.value 라는 값을 console.log에 더했다.
즉, 이벤트 핸들러(이벤트 함수)에 a라는 파라미터를 준 것이다.
이벤트 핸들러는 첫 번째 인자로 이벤트 객체를 전달한다.
id가 a인 엘리먼트를 변수 b에 담았고,
b.onclick = function(a) 는 id가 a인 엘리먼트 객체에서 onclick 이벤트가 실행될 때의 객체, 즉 button 타입의 input태그에 대한 객체가 되는 것이다.
a.target 에서 target 은 이벤트가 호출된 시점에서 그 이벤트가 어디에서 발생한 것 인지를 알려주는 프로퍼티이며,
a.target.value 는 발생된 이벤트의 value값을 의미한다.
button 타입의 input 태그에 대한 value는 test 이다.
따라서 button 클릭 시 console에 test message 에다가 input 엘리먼트의 value값이 더해진 값이 출력된다.
3) addEventListener() 방식
addEventListener 는 이벤트를 등록하는 방식 중에 가장 권장되는 방식이다.
그 이유는 몇 가지 장점이 존재하기 때문이다.
간단한 코드를 통해 확인해본다.
<input type="button" id="test" value="BUTTON" />
<script>
var b = document.getElementById('test');
b.addEventListener('click', function(a){
alert(a.target.id);
})
</script>
id가 test인 엘리먼트 객체를 b에 담았고,
b에 대해 addEventListener를 생성했다.
첫 번째 인자로 이벤트 타입을 받게 되어있고 해당 이벤트가 발생할 때 두 번째 인자가 실행이 된다.
즉, 여기선 "click 이벤트가 발생했을 때 function(a){} 가 실행됨을 의미한다.
두 번째 인자로 쓰여진 함수는 프로퍼티 방식과 동일하게 첫 번째 인자로 이벤트객체를 받는다.
따라서 결과는 위와 같이 나온다.
자 이제 addEventListener의 장점에 대해 확인해본다.
<input type="button" id="test" value="BUTTON" />
<script>
var b = document.getElementById('test');
b.addEventListener('click', function(a){
console.log(a.target.id);
})
b.addEventListener('click', function(a){
console.log(a.target.value);
})
</script>
test 라는 id의 앨리먼트 객체에 대해 클릭 이벤트가 발생했을 때 id 값과 value 값에 대해 콘솔창에 뜨도록 이벤트를 설치했다.
잘 나오는 것을 확인할 수 있다.
이것이 왜 장점이냐면,
프로퍼티 방식으로 코드를 짜서 실행시켜 보겠다.
<input type="button" id="test" value="BUTTON" />
<script>
var b = document.getElementById('test');
b.onclick = function(a){
console.log(a.target.id);
}
b.onclick = function(a){
console.log(a.target.value);
}
</script>
addEventListener가 아닌 onclick = function 으로 하여 프로퍼티 방식으로 코드를 짰다.
결과는,
아래에 있는 a.target.value 값만 콘솔창에 나오는 것을 볼 수 있다.
이벤트 핸들러는 하나만 저장되며 가장 마지막에 저장된 이벤트 핸들러만 호출이 되는 것이다.
하지만 addEventListener는 갱신되는 것이 아닌 추가가 되는 것이기에 하나의 이벤트 타겟에 대해 여러 이벤트 핸들러를 설치할 수 있게 되는 것이다.
반대로 하나의 이벤트 핸들러를 여러개의 이벤트 타겟에 설치할 수 있다.
<input type="button" id="test1" value="BUTTON1" />
<input type="button" id="test2" value="BUTTON2" />
<script>
var a = document.getElementById('test1');
var b = document.getElementById('test2');
function test(event){
switch(event.target.id){
case 'test1':
console.log("test1");
break;
case 'test2':
console.log("test2");
break;
}
}
a.addEventListener('click', test)
b.addEventListener('click', test)
</script>
test라는 함수를 만들고 switch 문을 이용해 id값이 test1이면 test1 문자열을 콘솔창에 출력하고,
id값이 test2라면 test2 문자열을 콘솔창에 출력하는 함수를 만들었다.
해당 함수를 각 button 타입의 input 태그의 엘리먼트 객체에 대해 addEventListener로 클릭이벤트 발생 시 test 함수가 호출되도록 설정했다.
button1,2 를 각각 클릭했을 때 잘 표현되는 것을 볼 수 있다.
이처럼 하나의 이벤트를 만들어놓고 여러 타겟에 설치하는 것이 가능하다.
'Javascript' 카테고리의 다른 글
19. 이벤트 기본동작 취소 (0) | 2021.09.29 |
---|---|
18. 이벤트 전파(버블링/캡처링) (0) | 2021.09.28 |
16. Node 종류 API (0) | 2021.09.18 |
15. Node 관계 API (0) | 2021.09.17 |
14. jQuery 조회 범위 제한 (0) | 2021.09.16 |