Javascript

circle live 10 ( 이벤트버블링, stopPropagation() )

2DC 2023. 1. 10. 20:33

 


 

 

 

 

 

코드 보기

<!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>
  1. screen div가 position fixed로 인해 모든 화면을 차지하고 있으며, const main으로 설정되어 있다.
  2. 따라서 화면의 어느 곳을 클릭하더라도 main.addEventListener('click', () => { }) 이 동작하게 된다.
  3. main 화면에 클릭이벤트가 감지되면 콜백함수가 실행되며, 생성자 함수 Circle이 실행된다.
  4. 생성자 함수 Circle은 이벤트 객체의 clientX좌표와 clientY좌표를 인수로 받는다.
  5. 생성자 함수는 circle 클래스명을 가진 동그란 div를 가지고 main에 append 된다. (즉, main의 자식요소가 된다.)
  6. 문제는 동그란 div들도 이벤트리스너를 가지고 생긴다는 점이다.
  7. 따라서 click 이벤트는 stopPropagation()이 없는 한 부모 요소로 계속 전파된다.
  8. 이 때, main도 클릭에 관한 이벤트리스너를 달고 있으므로, 이벤트가 겹치게 된다.
  9. 따라서 안정적인 동작을 위해서 (예기치 못한 상황을 막기 위해) DOM의 전파를 이해하고, 이벤트 버블링을 적절히 다룰 수 있어야 한다.