JS30 day25 Event Capture, Propagation, Bubbling and Once

Posted by Anthony Chao on 2019-11-26

JS30 day25 - Event Capture, Propagation, Bubbling and Once

作業內容

今天也是一個概念性的教學,在教捕捉跟冒泡機制,但這部分之前看書有看過所以覺得還好XD但是 once 這屬性是第一次看到,可以參考這份 CodePen的效果

學到什麼

  • js

    1. 捕捉跟冒泡:
      可以這樣理解:捕捉的時候從上到下捕捉,當我點擊 three 這個 div 的時候,其實所有包著他的 div 跟 body 也都會被點擊到
      捕捉的時候 DOM 會從外到內捕捉,先抓到 body 再依序到 three 這個 div,冒泡的時候就是從內到外,預設是隨著冒泡順序,所以下面的例子就是從裡到外觸發
    1
    2
    3
    4
    5
    6
    7
    8
    <body class="bod">
    <div class="one">
    <div class="two">
    <div class="three">
    </div>
    </div>
    </div>
    </body>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    divs = document.querySelectorAll('div', logText)

    function logText(){
    console.log(this.classList.value)
    }

    document.body.addEventListener('click', logText)
    divs.forEach(div => {
    div.addEventListener('click', logText)
    });
    // three two one bod

    要怎麼改變這個順序勒?我們可以在後面加上 capture: true(預設是 capture: false)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    divs = document.querySelectorAll('div', logText)

    function logText(){
    console.log(this.classList.value)
    }

    document.body.addEventListener('click', logText)
    divs.forEach(div => {
    div.addEventListener('click', logText, { capture: true })
    });
    // one two three bod
    1. stopPropogation() 可以讓事件不冒泡
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    divs = document.querySelectorAll('div', logText)

    function logText(e){
    console.log(this.classList.value);
    e.stopPropagation()
    }

    document.body.addEventListener('click', logText)
    divs.forEach(div => {
    div.addEventListener('click', logText)
    });
    // three
    1. once 這個新屬性是讓監聽只發生一次
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    divs = document.querySelectorAll('div', logText)

    function logText(e){
    console.log(this.classList.value)
    }

    divs.forEach(div => {
    div.addEventListener('click', logText,{
    once: true
    })
    });
    // 第一次按 => three two one
    // 第二次按 => (沒反應)

    上網查了一下,也有人會自己做出一個 once function,看這裡
    參考資料:
    https://github.com/wesbos/JavaScript30

code 內容:

HTML:

1
2
3
4
5
6
7
8
9
<body class="bod">

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

CSS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
html {
box-sizing: border-box;
}

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

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

.one {
background: thistle;
}

.two {
background: mistyrose;
}

.three {
background: coral;
}

JS:

1
2
3
4
5
6
7
8
9
10
11
divs = document.querySelectorAll('div', logText)

function logText(e){
console.log(this.classList.value)
}

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




prevent_hack