일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- BAEKJOON
- 백준
- 큐
- 모던자바스크립트
- 자료구조
- frontend
- programmers
- 일임형
- 프로그래머스
- 자바스크립트
- pyhton
- 신한투자증권
- JS
- 스택
- BFS
- 알고리즘
- React #Web #프런트엔드
- algoritms
- algorithms
- 파이썬
- JavaScript
- Algorithm
- 자문형
- Python
- SSAFY
- 로보어드바이저
- Ai
- RPA
- 혁신금융서비스
- dfs
- Today
- Total
Step by Step
Javascript 이벤트(추가, 삭제, 객체, 옵션, 버블링, 위임) 본문
addEventListener()
대상에 지정한 이벤트가 발생했을 때 함수(Handler)가 호출된다
const parentEl = document.querySelector(".parent");
const childEl = document.querySelector(".child");
parentEl.addEventListener("click", () => {
console.log("parent!");
});
childEl.addEventListener("click", () => {
console.log("child!");
});
removeEventListener()
대상에 지정한 이벤트를 제거한다.
removeEventListener를 사용할 때 콜백 함수 부분에 따로 설정한 함수가 들어가지 않으면 그 함수를 지정하는 줄 모르고 지우지 않는다.
const parentEl = document.querySelector(".parent");
const childEl = document.querySelector(".child");
const handler = () => {
console.log("parent!");
};
parentEl.addEventListener("click", handler);
childEl.addEventListener("click", () => {
parentEl.removeEventListener("click", handler);
});
// remove로 지워주려면 callback 함수가 아닌 handler라는 함수를 따로 만들어줘야함
이벤트 객체
이벤트 객체는 대상에서 발생한 이벤트 정보를 담고 있다
parent 부분을 클릭하면 parent,parent가 출력되지만 child 부분을 클릭하면 child, parent가 출력된다.
그 이유는 target은 지금 누른 것을 호출하지만 currentTarget은 등록되어 있는 부분 즉 조상을 호출하기 때문이다.
const parentEl = document.querySelector(".parent");
parentEl.addEventListener("click", (event) => {
console.log(event.target, event.currentTarget);
});
parentEl.addEventListener("wheel", (event) => {
console.log(event);
});
// target, currentTarget => 현재 타겟, 등록된 타겟
const inputEl = document.querySelector("input");
//input 태그안에 눌리는 키 출력
inputEl.addEventListener("keydown", (event) => {
console.log(event.key);
});
기본 동작 방지
마우스 휠의 스크롤 동작을 방지한다.
event.precentDefault()를 사용하면 적용된 이벤트 'wheel'이 실행이 안되지만 콘솔창에 'wheel!'은 출력이 된다
마찬가지로 a태그에도 적용해주면 클릭해서 다른 페이지로 이동하진 않지만 콘솔창에는 출력이 된다.
const parentEl = document.querySelector(".parent");
parentEl.addEventListener("wheel", (event) => {
event.preventDefault(); //스크롤이 안됨, wheel!은 뜸
console.log("wheel!");
});
//페이지 이동 방지
const anchorEl = document.querySelector("a");
anchorEl.addEventListener("click", (event) => {
event.preventDefault(); //a태그가 실행 안됨
console.log("click");
});
이벤트 전파(버블) 정지
event.stopPropagation()을 적용하기 전 a태그를 클릭하면 anchor, child, parent, body, window 순서로 출력이 된다.
event.stopPropagation()을 적용하면 적용된 부분까지만 출력되므로 parent부분에서 사용했다면 anchor, child, parent까지 나온다.
const parentEl = document.querySelector(".parent");
const childEl = document.querySelector(".child");
const anchorEl = document.querySelector("a");
window.addEventListener("click", (event) => {
console.log("Window");
});
document.body.addEventListener("click", (event) => {
console.log("body");
});
parentEl.addEventListener("click", (event) => {
console.log("parent");
event.stopPropagation(); //버블링 정지
});
childEl.addEventListener("click", (event) => {
console.log("child");
});
anchorEl.addEventListener("click", (event) => {
console.log("anchor");
});
// 버블링 정지 전 => anchor,child,parent,body,window
// 버블링 정지 후 => anchor, child, parent
//capture를 사용하면 제일 먼저 호출함
addEventListener() 뒤에 capture : true라는 객체를 추가해주면 그 부분이 가장 먼저 실행이된다.
원래는 anchor, child parent 순서대로 출력이 되야하지만 window, anchor, child , parent로 출력이 된다.
const parentEl = document.querySelector(".parent");
const childEl = document.querySelector(".child");
const anchorEl = document.querySelector("a");
window.addEventListener("click", (event) => {
console.log("Window");
},{capture : true});
document.body.addEventListener("click", (event) => {
console.log("body");
});
parentEl.addEventListener("click", (event) => {
console.log("parent");
event.stopPropagation(); //버블링 정지
});
childEl.addEventListener("click", (event) => {
console.log("child");
});
anchorEl.addEventListener("click", (event) => {
console.log("anchor");
});
// 버블링 정지 전 => anchor,child,parent,body,window
// 버블링 정지 후 => anchor, child, parent
//capture를 사용하면 제일 먼저 호출함
기본 동작과 핸들러 실행 분리
아래 코드에서 기본으로 동작하는 wheel과 1000까지 호출하는 함수가 있는데 passive : true라는 속성이 없다면 부하가 걸려 window 화면 내에서 버벅거릴 수 있다. passive : true가 있다면 아무리 큰 수라도 실행을 분리했기 때문에 멈춤 없이 동작한다.
const parentEl = document.querySelector(".parent");
parentEl.addEventListener(
"wheel",
() => {
console.log("parent");
for (let i = 0; i < 1000; i++) {
console.log(i);
}
},
{
passive: true,
}
);
//passive가 true면 wheel의 동작과 for문의 실행을 분리하므로 부하가 걸리지 않음
이벤트 위임
비슷한 패턴의 여러 요소에서 이벤트를 핸들링하는 경우
단일 조상 요소에서 제어하는 이벤트 위임 패턴을 사용할 수 있다.
조상 요소에 이벤트를 위임하는 경우는 parent 내에서 child클래스 본인을 포함해 가장 가까운 조상요소를 closest로 찾은 후 값이 null이 아니라면 child의 텍스트를 호출하므로 몇개의 요소라도 호출할 수 있다.
const parentEl = document.querySelector(".parent");
const childEls = document.querySelectorAll(".child");
//모든 대상 요소에 이벤트 등록
childEls.forEach((el) => {
el.addEventListener("click", (event) => {
console.log(event.target.textContent);
});
});
//조상 요소에 이벤트 위임
parentEl.addEventListener("click", (event) => {
const childEl = event.target.closest(".child");
if (childEl) {
console.log(childEl.textContent);
}
});
'Javascript Study' 카테고리의 다른 글
모던자바스크립트 Deep Dive - 4장(변수) (0) | 2024.02.08 |
---|---|
Javascript - Web API (1) | 2023.11.21 |
Javascript 이벤트(addEventListener) (0) | 2023.11.18 |
DOM(Node, Element, 생성 , 검색, 수정)-(1) (0) | 2023.09.06 |
비동기(Callback, Promise, Await, Async) (2) | 2023.09.04 |