버튼을 눌러도 개발자가 언제 클릭되는지 모르기 때문에 함수를 호출해야할지 모른다. 하지만 브라우저가 알 수 있기 때문에 함수 호출을 브라우저에게 위임하는 작업이 필요하다.
<body>
<h1>hello</h1>
<button onclick="sayHi('lee')">click me!</button>
<script>
function sayHi(name) {
console.log(`HI ${name}`);
}
</script>
</body>
</html>
함수 참조를 등록해야 이벤트 핸들러 등록이 가능하다.
- 함수를 반환하는 호출문을 등록시, 브라우저가 이벤트 핸들러로 등록할 수 없다.
<body>
<h1>hello</h1>
<button>Click here!</button>
<script>
const $button = document.querySelector('button');
$button.onclick = function () {
console.log('button click');
};
</script>
</body>
</html>
이벤트 타깃 : 이벤트를 발생 시킬 객체
이벤트 타입 : 이벤트 종류 - 문자열
Html 과 뒤섞이지 않고 사용할 수 있다는 장점이 존재하지만, 하나의 이벤트 핸들러만 바인딩할 수 있다는 단점이 존재한다.
<h1>hello</h1>
<button>Click here!</button>
<script>
const $button = document.querySelector('button');
$button.addEventListener('click', function () {
console.log('btn click');
});
</script>
<h1>hello</h1>
<button>Click here!</button>
<script>
const $button = document.querySelector('button');
$button.onclick = function () {
console.log('button click');
};
$button.addEventListener('click', function () {
console.log('[addEventListner] btn click');
});
</script>
버튼 클릭시 순차적으로 실행되었다는 것을 확인 할 수 있다.
EventTarget.prototype.removeEventListener
단, addEventListener와의 인수가 일치해야 한다.
$button.addEventListener('click', handleClick);
$button.removeEventListener('click', handleClick);
// 인수 일치로 삭제 가능
$button.removeEventListener('click', handleClick,true);
// 인수 불일치로 삭제 불가능
단, 한 번의 이벤트만 수행할 수 있게끔하기 위해서다.
<h1>hello</h1>
<button>Click here!</button>
<script>
const $button = document.querySelector('button');
$button.onclick = function () {
console.log('button click');
};
$button.addEventListener('click', function foo() {
console.log('[addEventListner] btn click');
$button.removeEventListener('click', foo);
});
</script>
</body>
이벤트 핸들러 프로퍼티로 등록된 이벤트 수행 후, addEventListener를 실행하게끔 했다.
addEventListener 안에 remove 시켜주니까 한 번 호출하고, onclick 만 동작하는 것을 확인 할 수 있다.
$button.addEventListener('click', function() {
console.log('[addEventListner] btn click');
$button.removeEventListener('click', arguments.callee);
});
만약 함수의 이름이 없다면 arguments.callee
를 사용하면 되는데 코드 최적화를 방해한다.
<h1>hello</h1>
<em class="message"></em>
<script>
const $msg = document.querySelector('.message');
function showcoor(e) {
$msg.textContent = `clinent-X : ${e.clientX}, client-Y : ${e.clientY}`;
}
document.onclick = showcoor;
</script>
아무 곳이나 좌표를 클릭하면 좌표의 위치를 알 수 있다.
클릭 이벤트를 통해 생성된 이벤트 객체는 이벤트 핸들러의 첫 번째 인수로 전달되어 e에 암묵적인 할당이 이루어진다.
공통 프로퍼티 | 설명 | 타입 |
---|---|---|
type | 이벤트 타입 | string |
target | 이벤트를 발생시킨 DOM 요소 | DOM 요소 노드 |
currentTarget | 이벤트 핸들러가 바인딩 된 DOM 요소 | DOM 요소 노드 |
eventPhase | 이벤트 전파 단계 [0 : 이벤트 없음 1: 캡처링 단계 2:타깃 단계 3: 버블링 단계 ] | number |
bubbles | 이벤트를 버블링으로 전파하는지 여부. | boolean |
cancleable | preventDefault(이벤트를 취소했는지 여부) 메서드 호출하여 이벤트 기본 동작을 취소할 수 있는지 여부 | boolean |
isTrusted | 사용자 행위에 의한 발생한 이벤트인지 여부 => 만약, 인위적으로 발생기킨 이벤트인 경우 isTrusted는 false 이다. | boolean |
timeStamp | 이벤트가 발생한 시각 | number |
<input type="checkbox" />
<em class="message">off</em>
<script>
const $checkbox = document.querySelector('input[type=checkbox]');
const $msg = document.querySelector('.message');
$checkbox.onchange = e => {
console.log(Object.getPrototypeOf(e) === Event.prototype);
$msg.textContent = e.target.checked ? 'on' : 'off';
};
</script>
사용자가 체크 박스 클릭시, change 이벤트 발생
-> Event 타입의 이벤트 객체 생성
-> (이벤트 객체의 target 프로퍼티는 이벤트를 발생시킨 객체를 나타냄) 즉, change 이벤트를 발생시킨 DOM 요소 $checkbox
-> checked 프로퍼티를 통해 체크 상태를 나타낸다.
e.target 도 $checkbox 가르키고, currentTarget 프로퍼티도 동일한 $checkbox 를 가르킨다. / 단 이벤트 위임에서는 다른 객체를 가르킬 수 있다.