코드 보기
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>circle 10 lives</title>
<style>
.screen {
position: fixed;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
background-color: azure;
}
.circle {
border-radius: 50%;
width: 100px;
height: 100px;
border: 2px solid black;
background: teal;
position: fixed;
text-align: center;
font-size: 30px;
padding-top: 25px;
box-sizing: border-box;
}
</style>
</head>
<body>
<div class="screen"></div>
</body>
<script>
const main = document.querySelector('.screen')
function Circle(x, y) {
let life = 10
y = y - 50
x = x - 50
const element = document.createElement('div')
element.classList.add('circle')
element.style.top = `${y}px`
element.style.left = `${x}px`
main.append(element)
element.innerText = life
element.addEventListener('click', (e) => {
life = life - 1
if (life <= 0) {
element.remove()
e.stopPropagation()
return
}
element.innerText = life
e.stopPropagation()
})
}
main.addEventListener('click', (e) => {
new Circle(e.clientX, e.clientY)
})
</script>
</html>
- screen div가 position fixed로 인해 모든 화면을 차지하고 있으며, const main으로 설정되어 있다.
- 따라서 화면의 어느 곳을 클릭하더라도 main.addEventListener('click', () => { }) 이 동작하게 된다.
- main 화면에 클릭이벤트가 감지되면 콜백함수가 실행되며, 생성자 함수 Circle이 실행된다.
- 생성자 함수 Circle은 이벤트 객체의 clientX좌표와 clientY좌표를 인수로 받는다.
- 생성자 함수는 circle 클래스명을 가진 동그란 div를 가지고 main에 append 된다. (즉, main의 자식요소가 된다.)
- 문제는 동그란 div들도 이벤트리스너를 가지고 생긴다는 점이다.
- 따라서 click 이벤트는 stopPropagation()이 없는 한 부모 요소로 계속 전파된다.
- 이 때, main도 클릭에 관한 이벤트리스너를 달고 있으므로, 이벤트가 겹치게 된다.
- 따라서 안정적인 동작을 위해서 (예기치 못한 상황을 막기 위해) DOM의 전파를 이해하고, 이벤트 버블링을 적절히 다룰 수 있어야 한다.
'Javascript' 카테고리의 다른 글
n x n 좌표 생성기 (1) (0) | 2023.01.29 |
---|---|
함수 장난 (1) (0) | 2023.01.27 |
[생성자 함수] 클릭하면 움직이는 원(circle) 만들기 (0) | 2022.12.05 |
[클래스] 클래스를 왜 배우는가? (0) | 2022.11.26 |
비디오 이벤트 연습(마우스 대면 플레이, 떼면 스탑 + 시간 카운트) (0) | 2022.10.31 |