新手村25 - Event Capture, Propagation, Bubbling and Once

25 - Event Capture, Propagation, Bubbling and Once

俗話說的好,一天一蘋果,醫生遠離我

一天一 JS,What the f*ck JavaScript?

small steps every day - 記錄著新手村日記

完成目標

Only addEventListener!Only addEventListener!Only addEventListener!

index_START.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Understanding JavaScript's Capture</title>
</head>
<body class="bod">

<div class="one">
<div class="two">
<div class="three">
</div>
</div>
</div>

<style>
html {
box-sizing: border-box;
}

*, *:before, *:after {
box-sizing: inherit;
}

div {
width: 100%;
padding: 100px;
}

.one {
background: thistle;
}

.two {
background: mistyrose;
}

.three {
background: coral;
}
</style>

<button></button>
<script>

</script>
</body>
</html>

JS - step by step

  1. Bubbling

    • 作業系統 到 瀏覽器 到 html 到 body 到 使用者 按的元素都會被觸發事件

    • 事件預設的執行順序是從元素往上到 body

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
       <script>
    const divs = document.querySelectorAll('div');
    const button = document.querySelector('button');

    button.addEventListener('click', () => {
    console.log('Click!!!');
    }
    </script>
    ```

    2. Event Capture

    - 瀏覽器做的事稱為捕捉
    - 意思是你點擊元素以跟到樹梢的順序捕捉所有的事件(與Bubble相反)

    ```javascript
    <script>
    const divs = document.querySelectorAll('div');
    const button = document.querySelector('button');

    function logText(e) {
    console.log(this.classList.value);
    // e.stopPropagation(); // stop bubbling!
    // console.log(this);
    }
    </script>
    ```

    3. Propagation

    - `stopPropagation()` 方法可阻止當前事件繼續進行捕捉及冒泡階段的傳遞
    - 設定 `capture:false` 取消預設行為,變成「點到誰,就是誰」
    - Event.stopPropagation():https://tinyurl.com/yy2qfbew

    ```javascript
    <script>
    const divs = document.querySelectorAll('div');
    const button = document.querySelector('button');
    //略
    divs.forEach(div => div.addEventListener('click', logText, {
    capture: false,
    once: true
    }));
    </script>
  2. Once(new property)

    • addEventListener 的第三個參數加上 once: false 會將行預設行為
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <script>
    const divs = document.querySelectorAll('div');
    const button = document.querySelector('button');
    //略
    button.addEventListener('click', () => {
    console.log('Click!!!');
    }, {
    once: true
    });
    </script>

    就大功告成啦!

JS - final

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script>
const divs = document.querySelectorAll('div');
const button = document.querySelector('button');

function logText(e) {
console.log(this.classList.value);
// e.stopPropagation(); // stop bubbling!
// console.log(this);
}

divs.forEach(div => div.addEventListener('click', logText, {
capture: false,
once: true
}));

button.addEventListener('click', () => {
console.log('Click!!!');
}, {
once: true
});

</script>

本刊同步於個人網站:http://chestertang.site/

本次範例程式碼原作者來源:https://tinyurl.com/yavm5f5n