Anthony Chao

JS30 day25 Event Capture, Propagation, Bubbling and Once

#Javascript

JS30 day25 - Event Capture, Propagation, Bubbling and Once

作業內容

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

學到什麼

  • js
    1. 捕捉跟冒泡: 可以這樣理解:捕捉的時候從上到下捕捉,當我點擊 three 這個 div 的時候,其實所有包著他的 div 跟 body 也都會被點擊到 捕捉的時候 DOM 會從外到內捕捉,先抓到 body 再依序到 three 這個 div,冒泡的時候就是從內到外,預設是隨著冒泡順序,所以下面的例子就是從裡到外觸發
    <body class="bod">
      <div class="one">
        <div class="two">
          <div class="three">
          </div>
        </div>
      </div>
    </body>
      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)
      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() 可以讓事件不冒泡
      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 這個新屬性是讓監聽只發生一次
    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:

<body class="bod">

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

CSS:

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:

divs = document.querySelectorAll('div', logText)

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

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