728x90
반응형
1. 이벤트 추가 및 제거
// addEventListener()
// 대상에 이벤트 청취(listen)를 등록
// 대상에 지정한 이벤트가 발생했을 때 지정한 함수(handler)가 호출
const parentEl = document.querySelector('.parent')
const childEl = document.querySelector('.child')
parentEl.addEventListener('click', ()=>{
console.log('Parent!')
})
childEl.addEventListener('click', ()=>{
console.log('childEl!')
})
// removeEventListener()
// 대상에 등록했던 이벤트 청취를 제거
// 메모리 관리를 위해 등록한 이벤트를 제거하는 과정이 필요
const handler = ()=>{
console.log('parent!')
}
parentEl.addEventListener('click', handler)
childEl.addEventListener('click', ()=>{
parentEl.removeEventListener('click', handler)
})
2. 이벤트 객체
// 이벤트 객체
// 대상에서 발생한 이벤트 정보를 담고 있음
const parentEl = document.querySelector('.parent')
// 콜백함수 인수로 event 객체가 들어와서 매개변수로 받음
// target : 이벤트가 발생한 해당 요소
// currentTarget : 이벤트가 등록된 요소
parentEl.addEventListener('click', (event)=>{
console.log(event.target, event.currentTarget)
console.log(event)
})
parentEl.addEventListener('wheel', (event)=>{
console.log(event)
})
const inputEl = document.querySelector('input')
inputEl.addEventListener('keydown', (event)=>{
console.log(event.key)
})
3. 기본 동작 방지
// 기본 동작 방지
// 마우스 휠의 스크롤 동작 방지
// 브라우저 결과에서 기본 동작이 필요하지 않을 때 preventDefault()로
// 이벤트 콜백 내부(이벤트 핸들러 내부)에서 실행해주면 됨
const parentEl = document.querySelector('.parent')
parentEl.addEventListener('wheel', event => {
// 해당 이벤트가 실제 발생하는 것을 막는 건 아니고
// 브라우저가 가지고 있는 기본적인 동작만 방지
// parent 요소 스크롤을 보여지지 않게 만든다는 것
event.preventDefault()
console.log('wheel!')
})
// <a> 태그에서 페이지 이동 방지
const anchorEl = document.querySelector('a')
anchorEl.addEventListener('click', event => {
event.preventDefault()
console.log('click!')
})
4. 버블링과 캡쳐링
// 이벤트 전파(버블) 정지
// 이벤트 버블은 후손 요소로부터 더 상위 요소로 이벤트가 전파
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')
// A 태그를 클릭하고, 이건 CHILD와 PARENT, BODY, WINDOW를 클릭한 것
// PARENT에 propagation 추가로 여기서 멈춤
event.stopPropagation() // 버블링 정지!
})
childEl.addEventListener('click', event => {
console.log('childEl')
})
anchorEl.addEventListener('click', event => {
console.log('anchor')
})
// 이벤트 캡쳐
// 캡쳐링 : 낮은 요소에서 조상 요소로 전파될 때, 중간 이벤트가 먼저 동작하게 하기 위함
// 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')
// event.stopPropagation() // child를 클릭해도 안나옴
// // capture를 걸어둔 곳이 먼저 동작됨
// }, {capture:true})
// parentEl.addEventListener('click', event => {
// console.log('parent')
// }, {capture:true})
// childEl.addEventListener('click', event => {
// console.log('childEl')
// })
// anchorEl.addEventListener('click', event => {
// console.log('anchor')
// })
// 예제2
const parentEl = document.querySelector('.parent')
const handler = () =>{
console.log('parent')
}
parentEl.addEventListener('click', handler, {
capture:true // 이벤트 제거할 때도 capture 추가해야함, 안그러면 동작안함
})
// 클릭하고 바로 제거해서 동작 안함
parentEl.removeEventListener('click', handler, {
// capture:true
})
5. 이벤트 옵션
// 이벤트 옵션
// 핸들러 한 번만 실행
const parentEl = document.querySelector('.parent')
parentEl.addEventListener('click', event => {
console.log('parent')
}, {
once:true
})
// 기본 동작과 핸들러 실행 분리
// 기본동작은 스크롤이나, 핸들러 실행 함수는 따로 동작됨
// passive가 없다면 처리할 로직이 많을수록 콘솔에서 부드럽지 않게 출력됨
// 사용성 좋아짐
parentEl.addEventListener('wheel', () => {
for (let i=0; i<10000; i+=1){
console.log(i)
}
}, {
passive:true
})
// html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="module" defer src="main.js"></script>
<style>
.parent {
width: 300px;
height: 200px;
margin-top: 1000px;
padding: 20px;
overflow: auto;
border: 10px solid;
}
.child {
width: 200px;
height: 1000px;
margin-top: 100px;
border: 10px solid;
background-color: orange;
font-size: 40px;
}
</style>
</head>
<body>
<div class="parent">
<div class="child">
<a href="https://naver.com" target="_blank">a</a>
</div>
</div>
</body>
</html>
728x90
반응형
'JS, TS' 카테고리의 다른 글
[JS] 기타 Web APIs (1) | 2024.01.15 |
---|---|
[JS] 이벤트 2 (0) | 2024.01.15 |
[JS] DOM (1) | 2024.01.14 |
[JS] 동기/비동기 (1) | 2024.01.14 |
[JS] 모듈 (0) | 2024.01.12 |