이벤트 핸들러 등록하기
onclick
프로퍼티도 innerHTML
처럼 새로운 이벤트 핸들러를 할당하게 되면 기존의 값을 덮어써서 문제를 발생할 수 있음
let btn = document.querySelector('#myBtn');
btn.onclick = function () {
console.log('Hi Codeit!');
};
btn.onclick = function () {
console.log('Hi again!');
};
elem.addEventListener(event, handler)
: 하나의 요소에 여러 개의 독립적인 이벤트 핸들러를 등록할 수 있는 메소드
- 가장 권장되는 이벤트 등록 방법임
- 함수의 이름만 전달해 주면 됨 (소괄호 붙이지 말기)
let btn = document.querySelector('#myBtn');
function event1() {
console.log('Hi Codeit!')
}
function event2() {
console.log('Hi again!')
}
btn.addEventListener('click', event1);
btn.addEventListener('click', event2);
btn.addEventListener('click', event2());
elem.removeEventListener(event, handler)
: 이벤트 핸들러 삭제
removeEventListener
메소드는 파라미터로 전달하는 타입과 이벤트 핸들러가 addEventListener
메소드로 등록할 때와 동일 할 때만 이벤트 핸들러를 삭제할 수 있음
- 이벤트를 삭제할 때는 등록했던 핸들러를 그대로 전달해야 함 (함수를 바로 써주면 안됨 -> 모양은 똑같지만 서로 다른 함수 이기 때문임)
btn.removeEventListener('click', event2);
다양한 이벤트
마우스 이벤트
키보드 이벤트
포커스 이벤트
입력 이벤트
스크롤 이벤트
윈도우 창 이벤트
이벤트 객체
- 웹 페이지에서 이벤트가 발생하면 관련된 정보를 담은 이벤트 객체가 만들어지고 이벤트 핸들러의 첫 번째 파라미터로 전달됨
- 공통적으로 자주 사용되는 프로퍼티는
type
과 target
프로퍼티임
const myInput = document.querySelector('#myInput');
const myBtn = document.querySelector('#myBtn');
function printEvent(event) {
console.log(event);
}
myInput.addEventListener('keydown', printEvent);
myBtn.addEventListener('click', printEvent);
이벤트 객체 프로퍼티
- 이벤트 객체는 이벤트 타입에 따라서 갖고 있는 프로퍼티들이 조금씩 다름
- 이벤트
공통 프로퍼티
- 이벤트 타입과 상관없이 모든 이벤트 객체들이 공통적으로 가지고 있는 프로퍼티
마우스 이벤트
키보드 이벤트
사용법
const toDoList = document.querySelector('#to-do-list');
const items = toDoList.children;
function updateToDo(event) {
event.target.classList.toggle('done');
}
for (let item of items) {
item.addEventListener('click', updateToDo)
}
이벤트 버블링
- 어떤 하나의 요소에 이벤트가 발생하게 되면 이 요소에 할당된 핸들러가 동작하고 거기서 끝이 아니라 같은 타입의 이벤트에 한해서 부모 요소의 핸들러도 동작하게 되는 것 (자식 요소에서 부모 요소로 이벤트가 전파되는 것)
- 이벤트 버블링이 일어나도 이벤트 객체의
target
프로퍼티는 변하지 않고 처음 이벤트가 발생한 시작점을 담고 있음
currentTarget
프로퍼티: 실제로 이벤트 핸들러가 동작하는 요소가 출력됨
e.stopPropagation();
: 버블링을 멈추는 법 (사용하지 않는 편이 좋음)
캡쳐링
- 이벤트가 발생하면 가장 먼저, 그리고 버블링의 반대 방향으로 진행되는 이벤트 전파 방식
- 캡쳐링 단계에서 이벤트 핸들러를 동작시키려면,
addEventListener
에 세번째 프로퍼티에 true
또는 { capture:true }
를 전달하면 됩
이벤트 흐름
- 캡처링 단계: 이벤트가 하위 요소로 전파되는 단계
- 타깃 단계: 이벤트가 실제 타깃 요소에 전달되는 단계 -> 가장 처음 이벤트 핸들러가 동작하게 되는 순간
- 버블링 단계: 이벤트가 상위 요소로 전파되는 단계
이벤트 위임
- Event Delegation: 자식 요소에서 발생하는 이벤트를 부모 요소에서 다루는 방식 (자식 요소의 이벤트를 부모 요소에 위임하는 것)
- 새로운 자식 요소를 추가하거나 삭제하더라도 이벤트에 대한 제어를 이 자식 요소에 신경 쓰지 않아도 되기 때문에 유연하게 코드를 작성할 수 있음
- 버블링을 이용함
- 우리가 원하는 자식 요소에서 동작 되도록 처리를 잘 해줘야함
const list = document.querySelector('#list');
list.addEventListener('click', function(e) {
if (e.target.classList.contains('item')) {
e.target.classList.toggle('done');
}
});
const li = document.createElement('li');
li.classList.add('item');
li.textContent = '일기 쓰기';
list.append(li);
li.addEventListener('click', function(e) {
e.stopPropagation();
});
tagName
프로퍼티: 해당 요소의 태그 이름값을 대문자로 담고 있는 프로퍼티
classList.contains
메소드: 파라미터로 전달하는 값이 해당 요소의 클래스 속성에 있는지를 확인해서 불린 형태로 결과를 리턴해줌
브라우저의 기본 동작
event.preventDefault
: 브라우저의 기본 동작을 막음
const link = document.querySelector('#link');
const checkbox = document.querySelector('#checkbox');
const input = document.querySelector('#input');
const text = document.querySelector('#text');
link.addEventListener('click', function(e) {
e.preventDefault();
alert('지금은 이동할 수 없습니다.');
});
input.addEventListener('keydown', function(e) {
if (!checkbox.checked) {
e.preventDefault();
alert('체크박스를 먼저 체크해 주세요.');
}
});
document.addEventListener('contextmenu', function(e) {
e.preventDefault();
alert('마우스 오른쪽 클릭은 사용할 수 없습니다.');
});
참고 자료