본문 바로가기

클라이언트/JavaScript
자바스크립트(JavaScript) 이벤트

//이벤트, Event

    - 사건
    - 객체(혹은 태그)에서 발생하는 사건
    - 언제 발생할지 예측 불가능(시간)


// JavaScript Event Handling★★
    - 이벤트 등록(구현)
    - 사건 처리
    - 언제 발생할지 예측 불가능한 사건에 대해 처리를 하고 싶다. > 언젠가 사건이 발생하면 처리하기 위한 코드를 미리 준비한다. > 사건과 연결 > 이벤트 처리, 이벤트 매핑, 이벤트 구현 등
    
    1. 정적
        - HTML 코드에 직접 사용
    
    2. 동적
        - JavaScript 코드를 사용  

    - this: 이벤트 주체(이벤트가 걸린 태그)
        ※ 함수 내의 this는 window 객체(전역 객체)를 말한다.


<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <style>
        
        form > input {
            display: block;
            margin-bottom: 5px;
            padding: 5px;
        }
        
    </style>
</head>
<body>
    
    <h1>Event</h1>
    
    <form name="form1">
        <input type="text" name="txt1">
        
        <input type="button" value="확인(정적이벤트)" name="btn1" onclick="window.document.form1.txt1.value = '홍길동';"> <!--1. 정적-->
        
        <input type="button" value="확인(동적이벤트)" name="btn2">
    </form>
    
    <script>
        
        // 2. 동적
         window.document.form1.btn2.onclick =  m1; // ()없음! 호출xx / 함수 포인터 > 언젠가는 찾아가서 실행
        
         function m1() {
             window.document.form1.txt1.value = '아무개';
         }
       
    </script>
    
</body>
</html>

// 마우스 관련 이벤트

    - onmouseXXX
    
    1. onmouseover(= onmouseenter)
        - 해당 객체의 영역에 마우스(커서)가 진입하는 순간 발생
    2. onmouseout(= onmouseleave)
        - 해당 객체의 영역에서 마우스(커서)가 빠져나가는 순간 발생

    3. onmousedown
        - 해당 객체의 영역에서 마우스 버튼을 누르는 순간 발생
    4. onmouseup
        - 해당 객체의 영역에서 마우스 버튼을 떼는 순간 발생

    5. onmousemove
        - 해당 객체의 영역에서 마우스가 움직일 때마다 발생


    ~ event.buttons: 마우스 버튼의 번호
        - 왼쪽(1), 오른쪽(2), 왼쪽+오른쪽(3), 휠버튼(4)

    ~ 마우스 커서 좌표     
        1. x, y
            - 문서 좌측 상단을 기준으로 한다.
            - 비표준(MS-IE) > 비권장
            
        2. clientX, clientY★★★★★
            - 문서 좌측 상단을 기준으로 한다.
            - 표준 > 권장
            ≒ CSS > position: absolute;
            
        3. screenX, screenY
            - 모니터 좌측 상단을 기준
            - 일상적으로는 다루기가 힘들다.
        
        4. offsetX, offsetY★★★★★
            - 이벤트 객체의 좌측 상단을 기준
            - 자기 자신이 기준이 된다.
            ≒ CSS > position: relative;

    ~ event.target, event.srcElement : 눌린 버튼의 프로퍼티 제공


    * onclick: 클릭했을 때 나타나는 이벤트
    * onchange: 입력 컨트롤의 값이 변할 때 발생하는 이벤트
    * oninput: 입력 컨트롤의 값이 변하는 것을 실시간으로 보여주는 이벤트


- onmouseover, onmouseout

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <style>
        textarea, input {
            display: block;
            margin-bottom: 10px;
        }        
        
        textarea {
            width: 500px;
            height: 300px;
            outline: none;
            resize: none;
        }
        
    </style>
</head>
<body>
    
    <h1>마우스 관련 이벤트</h1>
    
    <form name="form1">
        <textarea name="txt1"></textarea>
        <input type="button" value="확인" name="btn1">
    </form>
    
    <script>
        
        function message(txt) {
            var now = new Date();
            txt1.value = txt + '-' + now.toLocaleTimeString() + '\r\n' + txt1.value;            
        }
        
        var txt1 = window.document.form1.txt1;
        var txt2 = window.document.form1.btn1;
        
        txt1.onmouseover = m1;
        
        function m1() {
            message('mouseover');
        }
        
        txt1.onmouseout = m2;
        
        function m2() {            
            message('mouseout');
        }
        
    </script>
    
</body>
</html>

 

- onmousedown / onmouseup

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <style>
        textarea, input {
            display: block;
            margin-bottom: 10px;
        }        
        
        textarea {
            width: 500px;
            height: 300px;
            outline: none;
            resize: none;
        }
        
    </style>
</head>
<body>
    
    <h1>마우스 관련 이벤트</h1>
    
    <form name="form1">
        <textarea name="txt1"></textarea>
        <input type="button" value="확인" name="btn1">
    </form>
    
    <script>
        
        function message(txt) {
            var now = new Date();
            txt1.value = txt + '-' + now.toLocaleTimeString() + '\r\n' + txt1.value;            
        }
        
        var txt1 = window.document.form1.txt1;
        var txt2 = window.document.form1.btn1;
        
        txt1.onmousedown = m3;
        
        function m3() {
            message('messagedown');
        }
        
        txt1.onmouseup = m4;
        
        function m4() {
            message('messageup');
        }
        
    </script>
    
</body>
</html>

- onmousemove

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <style>
        textarea, input {
            display: block;
            margin-bottom: 10px;
        }        
        
        textarea {
            width: 500px;
            height: 300px;
            outline: none;
            resize: none;
        }
        
    </style>
</head>
<body>
    
    <h1>마우스 관련 이벤트</h1>
    
    <form name="form1">
        <textarea name="txt1"></textarea>
        <input type="button" value="확인" name="btn1">
    </form>
    
    <script>
        
        function message(txt) {
            var now = new Date();
            txt1.value = txt + '-' + now.toLocaleTimeString() + '\r\n' + txt1.value;            
        }
        
        var txt1 = window.document.form1.txt1;
        var txt2 = window.document.form1.btn1;
        
        var n = 1;
        
        txt1.onmousemove = m5;
        
        function m5() {  
            message('messagemove - ' + n);
            n++
        }        
        
    </script>
    
</body>
</html>

- event.buttons

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <style>
        textarea, input {
            display: block;
            margin-bottom: 10px;
        }        
        
        textarea {
            width: 500px;
            height: 300px;
            outline: none;
            resize: none;
        }
        
    </style>
</head>
<body>
    
    <h1>마우스 관련 이벤트</h1>
    
    <form name="form1">
        <textarea name="txt1"></textarea>
        <input type="button" value="확인" name="btn1">
    </form>
    
    <script>
        
        function message(txt) {
            var now = new Date();
            txt1.value = txt + '-' + now.toLocaleTimeString() + '\r\n' + txt1.value;            
        }
        
        var txt1 = window.document.form1.txt1;
        var txt2 = window.document.form1.btn1;
        
        txt1.onmousedown = m3;
        
        function m3() {
            
            // message(event.buttons); //마우스 어떤 버튼인지 알 수 있다.
            if(event.buttons == 2) {
                alert('오른쪽 버튼 클릭 금지');
            }
            
        }
        
    </script>
    
</body>
</html>

- x, y

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <style>
        textarea, input {
            display: block;
            margin-bottom: 10px;
        }        
        
        textarea {
            width: 500px;
            height: 300px;
            outline: none;
            resize: none;
        }
        
    </style>
</head>
<body>
    
    <h1>마우스 관련 이벤트</h1>
    
    <form name="form1">
        <textarea name="txt1"></textarea>
        <input type="button" value="확인" name="btn1">
    </form>
    
    <script>
        
        function message(txt) {
            var now = new Date();
            txt1.value = txt + '-' + now.toLocaleTimeString() + '\r\n' + txt1.value;            
        }
        
        var txt1 = window.document.form1.txt1;
        var txt2 = window.document.form1.btn1;
        
        txt1.onmousedown = m3;
        
        function m3() {
            
            message(event.x + ',' + event.y); 
            
        }
                
    </script>
    
</body>
</html>

- offsetX, offsetY

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <style>
        textarea, input {
            display: block;
            margin-bottom: 10px;
        }        
        
        textarea {
            width: 500px;
            height: 300px;
            outline: none;
            resize: none;
        }
        
    </style>
</head>
<body>
    
    <h1>마우스 관련 이벤트</h1>
    
    <form name="form1">
        <textarea name="txt1"></textarea>
        <input type="button" value="확인" name="btn1">
    </form>
    
    <script>
        
        function message(txt) {
            var now = new Date();
            txt1.value = txt + '-' + now.toLocaleTimeString() + '\r\n' + txt1.value;            
        }
        
        var txt1 = window.document.form1.txt1;
        var txt2 = window.document.form1.btn1;
        
        txt1.onmousedown = m3;
        
        function m3() {
            
            message(event.offsetX + ',' + event.offsetY);
            
        }        
        
    </script>
    
</body>
</html>

// onclick 

- 마우스를 클릭할 때 발생하는 이벤트


<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <style>
        textarea, input {
            display: block;
            margin-bottom: 10px;
        }        
        
        textarea {
            width: 500px;
            height: 300px;
            outline: none;
            resize: none;
        }
        
    </style>
</head>
<body>
    
    <h1>마우스 관련 이벤트</h1>
    
    <form name="form1">
        <textarea name="txt1"></textarea>
        <input type="button" value="확인" name="btn1">
    </form>
    
    <script>
        
        function message(txt) {
            var now = new Date();
            txt1.value = txt + '-' + now.toLocaleTimeString() + '\r\n' + txt1.value;            
        }
        
        var txt1 = window.document.form1.txt1;
        var btn1 = window.document.form1.btn1;
        
        //onclick > 마우스 이벤트 x
        btn1.onclick = m6;
        
        function m6() {
            
            //onclick 내에서는 마우스에 대한 정보를 알 수 없다.
            message('onclick' + event.buttons);
        }        
        
    </script>
    
</body>
</html>

// 키 관련 이벤트        
    - onkeyXXX
    - 포커스를 가지는 태그에서만 발생(텍스트 박스, 체크 박스 등)
        > 이미지 등의 태그에서 사용하려면 window에 걸어야 한다. > 전역 이벤트(화면의 모든 곳에서 발생)
    - 발생 순서: keydown > keypress > keyup
    
        1. onkeydown
            - 키를 눌렀을 때 발생
            - 문자에 반응하는 이벤트 X / 물리키에 반응하는 이벤트 O
            - 물리키에 반응하는 이벤트 > 어떤 키를 눌렀는지가 중요하다.
            - 키보드에 존재하는 모든 키에 반응한다.★★★★★★
        
        2. onkeyup
            - 키를 뗐을 때 발생
        
        3. onkeypress
            - 키를 눌렀을 때 발생
            - 문자에 반응하는 이벤트 O / 물리키에 반응하는 이벤트 X
            - 문자가 아닌 키에는 반응하지 않는다.★★★★★★
            - 잘 사용하지 않는다.

        ~ event.keyCode: 입력값 코드
            - 좌(37), 상(38), 우(39), 하(40)


- onkeydown / onkeyup / onkeypress

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <style>
        input, textarea {
            display: block;
            margin-bottom: 10px;
            outline: none;
        }        
    </style>
</head>
<body>
    
    <h1>키 이벤트</h1>
    
    <form name="form1">
        <input type="text" name="txt1">
        <input type="text" name="txt2">        
        <textarea name="txt3"></textarea>
    </form>
    
    <script>
        
        var txt1 = window.document.form1.txt1;
        var txt2 = window.document.form1.txt2;
        var txt3 = window.document.form1.txt3;
        
        txt1.onkeydown = m1;
        txt1.onkeyup = m2;
        txt1.onkeypress = m3;
        
        
        function m1(evt) {
            console.log('keydown');  
        }
        
        function m2() {
            console.log('keyup');           
        }
        
        function m3() {
            console.log('keypress');             
        }                
        
    </script>
    
</body>
</html>

- evt.keyCode

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <style>
        input, textarea {
            display: block;
            margin-bottom: 10px;
            outline: none;
        }        
    </style>
</head>
<body>
    
    <h1>키 이벤트</h1>
    
    <form name="form1">
        <input type="text" name="txt1">
        <input type="text" name="txt2">        
        <textarea name="txt3"></textarea>
    </form>
    
    <script>
        
        var txt1 = window.document.form1.txt1;
        var txt2 = window.document.form1.txt2;
        var txt3 = window.document.form1.txt3;
        
        txt3.onkeydown = m1;
        txt3.onkeyup = m2;
        txt3.onkeypress = m3;
        
        
        function m1(evt) {
            console.log(evt.keyCode);    
            
            if (evt.keyCode == 37) {
                txt3.cols--;
            } else if (evt.keyCode == 39) {
                txt3.cols++;
            } else if (evt.keyCode == 38) {
                txt3.rows++;
            } else if (evt.keyCode == 40) {
                txt3.rows--;
            }
              
        }
        
        function m2() {
            // console.log('keyup');     
            // console.log(event.keyCode);              
        }
        
        function m3() {
            // console.log('keypress');       
            // console.log(event.keyCode);          
        }        
        
    </script>
    
</body>
</html>

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <style>

        .item {
            border: 1px solid #CCC;
            background-color: #EEE;
            padding: 10px;
            margin: 15px;
            width: 400px;
            text-align: center;
        }

        .item > input[type=button] {
            border: 1px solid #CCC;
            background-color: #FFF;
            width: 100px;
            height: 60px;
            margin: 10px;
            outline: none;
        }

    </style>
</head>
<body>
    
    <h1>다량의 요소(태그)의 이벤트 처리</h1>

    <div class="item">
        <input type="button" name="btnRed" value="빨강" onclick="m1();">
        <input type="button" name="btnYellow" value="노랑" onclick="m2();">
        <input type="button" name="btnBlue" value="파랑" onclick="m3();">
    </div>

    <div class="item">
        <input type="button" name="btnRed2" value="빨강">
        <input type="button" name="btnYellow2" value="노랑">
        <input type="button" name="btnBlue2" value="파랑">
    </div>

    <div class="item">
        <input type="button" value="빨강" onclick="m7('tomato');">
        <input type="button" value="노랑" onclick="m7('gold');">
        <input type="button" value="파랑" onclick="m7('cornflowerblue');">
    </div>

    <div class="item">
        <input type="button" value="빨강" onclick="m8(this);">
        <input type="button" value="노랑" onclick="m8(this);">
        <input type="button" value="파랑" onclick="m8(this);">
    </div>

    <div class="item">
        <input type="button" name="btnTomato" value="빨강" onclick="m9(this);">
        <input type="button" name="btnGold" value="노랑" onclick="m9(this);">
        <input type="button" name="btnCornflowerblue" value="파랑" onclick="m9(this);">
    </div>

    <div class="item">
        <input type="button" name="btnRed" value="빨강" onclick="m10(this);" data-color="tomato">
        <input type="button" name="btnYellow" value="노랑" onclick="m10(this);" data-color="gold">
        <input type="button" name="btnBlue" value="파랑" onclick="m10(this);" data-color="cornflowerblue">
    </div>

    <div class="item">
        <input type="button" name="btnRed" value="빨강" onclick="m11();" data-color="tomato">
        <input type="button" name="btnYellow" value="노랑" onclick="m11();" data-color="gold">
        <input type="button" name="btnBlue" value="파랑" onclick="m11();"  data-color="cornflowerblue">
    </div>

    <div class="item">
        <input type="button" name="btnRed3" value="빨강" data-color="tomato">
        <input type="button" name="btnYellow3" value="노랑" data-color="gold">
        <input type="button" name="btnBlue3" value="파랑" data-color="cornflowerblue">
    </div>

    <div class="item">
        <input type="button" name="btn" value="빨강" data-color="tomato">
        <input type="button" name="btn" value="노랑" data-color="gold">
        <input type="button" name="btn" value="파랑" data-color="cornflowerblue">
    </div>

    <hr>

    <script>

        function m1() {
            document.body.bgColor = 'tomato';
        }

        function m2() {
            document.body.bgColor = 'gold';
        }

        function m3() {
            document.body.bgColor = 'cornflowerblue';
        }

        document.all.btnRed2.onclick = m4;
        document.all.btnYellow2.onclick = m5;
        document.all.btnBlue2.onclick = m6;

        function m4() {
            document.body.bgColor = 'tomato';
        }

        function m5() {
            document.body.bgColor = 'gold';
        }

        function m6() {
            document.body.bgColor = 'cornflowerblue';
        }

        function m7(color) {
            document.body.bgColor = color;
        }

        //함수 내의 this는 window 객체를 말한다.
        function m8(btn) {
            // alert(btn.value);
            // alert(this.value)

            if (btn.value == '빨강') {
                document.body.bgColor = 'tomato'; 
            } else if(btn.value == '노랑') {
                document.body.bgColor = 'gold';
            } else if(btn.value == '파랑'){
                document.body.bgColor = 'cornflowerblue';
            }
        }

        function m9(btn) {
            document.body.bgColor = btn.name.substring(3);
        }

        function m10(btn) {
            // alert(btn.dataset['color']);
            document.body.bgColor = btn.dataset['color']
        }

        function m11() {
            
            //어떤 버튼이 눌렸는지?
            //- event 객체 > 눌린 버튼 프로퍼티 제공
            // alert(event.srcElement)
            // alert(event.target)

            // alert(event.target.dataset['color']);

            document.body.bgColor = event.target.dataset['color'];
        }

        document.all.btnRed3.onclick = m12;
        document.all.btnYellow3.onclick = m12;
        document.all.btnBlue3.onclick = m12;

        function m12() {
            document.body.bgColor = event.target.dataset['color'];
        }

        //name='btn' 배열
        //1. name 유일 > 단일 객체
        //2. name 중복 > 배열
        // alert(document.all.btn.length);

        for(var i = 0; i < document.all.btn.length; i++) {
            document.all.btn[i].onclick = m13;
        }

        function m13() {
            document.body.bgColor = event.target.dataset['color'];
        }

    </script>

</body>
</html>

// DOM 이벤트

        ~ addEventListener(원하는조작, 함수)    > 이벤트 설정
        ~ removeEventListener(원하는조작, 함수) > 이벤트 제거
        - 이벤트 매핑을 관리할 수 있다.
            > Invocation List(이벤트 함수 목록)


- addEventListener

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <style>
    
    </style>
</head>
<body>

    <h1>DOM Event</h1> 

    <input type="button" value="BOM" id="btn1" name="btn1"> 
    <input type="button" value="DOM" id="btn2" name="btn2"> 

    <script>
    	
        const btn1 = document.getElementById('btn1');
        const btn2 = document.getElementById('btn2');
    
        //이벤트 매핑을 관리할 수 있다.
        btn2.addEventListener('click', m1);
        btn2.addEventListener('click', m2); //누적

        function m1() {
            alert('m1');
        }

        function m2() {
            alert('m2');
        }

    </script>

</body>
</html>

- removeEventListener

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <style>
    
    </style>
</head>
<body>

    <h1>DOM Event</h1> 

    <input type="button" value="BOM" id="btn1" name="btn1"> 
    <input type="button" value="DOM" id="btn2" name="btn2"> 

    <script>

        const btn1 = document.getElementById('btn1');
        const btn2 = document.getElementById('btn2');

        //이벤트 매핑을 관리할 수 있다.
        btn2.addEventListener('click', m1);
        btn2.addEventListener('click', m2); //누적
        btn2.removeEventListener('click', m1)

        function m1() {
            alert('m1');
        }

        function m2() {
            alert('m2');
        }

    </script>

</body>
</html>

// 이벤트 버블링(Event Bubbling), 이벤트 터널링(Event Tunneling, 이벤트 캡쳐링(Event Capturing))

    - 이벤트는 태그 계층구조에 따라 순차적으로 전달 및 실행된다.
        ~ 이벤트 터널링: 상위 계층부터 하위 계층까지 순차적으로 이벤트를 전달한다.
        ~ 이벤트 버블링: 하위 계층부터 상위 계층까지 순차적으로 이벤트를 수행한다.
    
    - 자바스크립트는 기본적으로 이벤트만 발생한다.(원하면 이벤트 터널링도 발생시킬 수는 있다. > DOM으로만 가능)
        > 내려가다가 이벤트가 걸린 곳에서 유턴한다.
            - event.target★★ , event.srcElement: 유턴하는 객체
            - this, event.currentTarget★★: 이벤트를 소유하는 객체

    - addEventListener(원하는조작, 함수, true): 이벤트 터널링 구현

    - 이벤트 버블링 중단(이벤트 발생 사실을 상위 계층에 알리지 않는다.)
        1. event.cancelBubble = true; > 비표준(MS) > IE 전용
        2. event.stopPropagation();   > 표준 > 권장


- BOM

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <style>
        .box { padding: 50px; }
        #p1 { background-color: tomato;}
        #p2 { background-color: gold;}
        #p3 { background-color: cornflowerblue;}
    </style>
</head>
<body>

    <div id="p1" class="box">
        <div id="p2" class="box">
            <div id="p3" class="box"></div>
        </div>
    </div>

    <script>
        
        const p1 = document.getElementById('p1')
        const p2 = document.getElementById('p2')
        const p3 = document.getElementById('p3')

        //이벤트 버블링(Event Bubbling) 
        // vs 이벤트 터널링(Event Tunneling, 이벤트 캡쳐링(Event Capturing))

        p1.onclick = function () {
            alert('빨강' + event.target.id);
        };

        p2.onclick = function() {
            // alert('노랑' + event.target.id + event.srcElement.id + this.id + event.currentTarget.id);
            alert('노랑' + event.target.id);
        };

        p3.onclick = function() {
            alert('파랑' + event.target.id);
            event.cancelBubble = true;
        };

    </script>

</body>
</html>

- DOM( 이벤트 터널링)

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <style>
        .box { padding: 50px; }
        #p1 { background-color: tomato;}
        #p2 { background-color: gold;}
        #p3 { background-color: cornflowerblue;}
    </style>
</head>
<body>

    <div id="p1" class="box">
        <div id="p2" class="box">
            <div id="p3" class="box"></div>
        </div>
    </div>

    <script>
        
        
        const p1 = document.getElementById('p1')
        const p2 = document.getElementById('p2')
        const p3 = document.getElementById('p3')

        //DOM

        //이벤트 터널링

        p1.addEventListener('click', function() {
            alert('빨강');
        }, true);

        p2.addEventListener('click', function() {
            alert('노랑');
        }, true);

        p3.addEventListener('click', function() {
            alert('파랑');
        }, true);

        //이벤트 버블링

        p1.addEventListener('click', function() {
            alert('빨강');
        });

        p2.addEventListener('click', function() {
            alert('노랑');
        });

        p3.addEventListener('click', function() {
            alert('파랑');
        });

    </script>

</body>
</html>