事件傳播機制-事件捕獲-事件-冒泡-事件委託

<!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{
            box-sizing: border-box;
            margin:20px auto;
            padding-top: 20px;
            width: 300px;
            height: 300px;
            background: lightblue;
        }
        .outer{
            box-sizing: border-box;
            margin: 0 auto;
            padding-top: 20px;
            width: 200px;
            height: 200px;
            background: lightcoral;
        }
        .inner{
            margin: 0 auto;
            width: 100px;
            height: 100px;
            background: lightgoldenrodyellow;
        }
    </style>
</head>
<body>
    <div class="box">box
        <div class="outer">outer
            <div class="inner">inner</div>
        </div>
    </div>

    <script>
        let box = document.querySelector('.box'),
        outer = document.querySelector('.outer'),
        inner = document.querySelector('.inner');

        /**
         * DOM 0級 綁定中給元素事件綁定的方法, 都是在目標階段 =》 冒泡階段觸發的
         * 從裏 往外  inner =》 outer => box
        */
 
        // inner.onclick = function(ev){
        //     console.log('inner=>',ev);
        // }

        // outer.onclick = function(ev){
        //     console.log('outer=>',ev);
        // }

        // box.onclick = function(ev){
        //     console.log('box=>',ev);
        // }

        // document.body.onclick = function(ev){
        //     console.log('body=>',ev);
        // }

        
        /**
         * DOM 2級 綁定中給元素事件綁定的方法, 都是在捕獲階段觸發的
         *    + 默認是 false 冒泡階段觸發 從裏 往外  inner =》 outer => box
         *    + 設置爲true   捕獲階段觸發 從外 往裏  box   =》 outer => inner
        */

        // inner.addEventListener('click',function(ev){
        //     console.log('inner=>',ev);
        // },true)

        // outer.addEventListener('click',function(ev){ 
        //     console.log('outer=>',ev);
        // },true)

        // box.addEventListener('click',function(ev){ 
        //     console.log('box=>',ev);
        // },true)




        // inner.onclick = function(ev){ 
        //     //阻止冒泡
        //     // ev.stopPropagation ? ev.stopPropagation() : ev.cancelBubble();
        //     ev.stopPropagation();
        //     console.log('inner=>',ev);
        // }

        // outer.onclick = function(ev){
        //     ev.stopPropagation();
        //     console.log('outer=>',ev);
        // }

        // box.onclick = function(ev){
        //     ev.stopPropagation();
        //     console.log('box=>',ev);
        // }

        // document.body.onclick = function(ev){
        //     ev.stopPropagation();
        //     console.log('body=>',ev);
        // }


        // --------------------------------------------------
        /**
         * 由於點擊事件行爲存在冒泡傳播機制,因此不論點擊  box、outer、inner,最後都會
         * 傳遞到 body 上, 觸發body的 click 點擊事件行爲,把爲其綁定的方法執行
         *  
         *   在方法執行接收到的事件對象中,有一個 target/srcElement屬性(事件源),能夠知道當前點擊的是誰,此時
         *    方法中 能夠根據事件源的不一樣,作不一樣的處理
         *     這就是 「事件委託/事件代理」: 利用事件的冒泡傳播機制,能夠把一個容器中全部後代元素的某個
         *      事件行爲觸發要作的操做,委託給當前容器的某個事件行爲,後期只要觸發任意後代元素,在方法執行的時候,
         *      基於事件源 作不一樣的處理
         *      + 性能高
         *      + 能夠操做動態綁定的元素
         *      + 某些需求必須基於它完成 
         *      + ...
         * */ 
         document.body.onclick = function(ev){
            // console.log(ev); 
            let target = ev.target,
                tgrgetClass = target.className;
            // console.log(tgrgetClass); // inner
            if(tgrgetClass === "inner"){
                console.log('inner');
                return;
            }else if(tgrgetClass === "outer"){
                console.log('outer');
                return;
            }else if(tgrgetClass === "box"){
                console.log('box');
                return;
            }
         }

    </script>
</body>
</html>
相關文章
相關標籤/搜索