事件冒泡的应用

首先说一下事件冒泡和事件捕获
1.事件捕获:
何为事件捕获(event capturing)?事件从最不精确的对象开始出发,到最精确的对象。即从window->document->documentElement->body->Dom元素->直到捕获到事件。
2.事件冒泡:
与事件捕获刚好相反。事件从最确定的事件目标到最不确定的事件目标。

// HTML
 <div id="div">
     我是div
     <p id="p1">
         我是第一段<span id="p2">我是第二段</span>
     </p>
 </div>
 //获取对象
<script>
    let div = document.getElementById('div');
    let p = document.getElementById('p1');
    let span = document.getElementById('p2');
</script>
 //捕获阶段
 window.addEventListener('click',(e)=>{
      console.log(`window捕获${e.target.nodeName},当前对象为${e.currentTarget.nodeName}`)
  },true)
  document.addEventListener('click',(e)=>{
      console.log(`document捕获${e.target.nodeName},当前对象为${e.currentTarget.nodeName}`)
  },true)
  document.documentElement.addEventListener('click',(e)=>{
      console.log(`document.documentElement捕获${e.target.nodeName},当前对象为${e.currentTarget.nodeName}`)
  },true)
  document.body.addEventListener('click',(e)=>{
      console.log(`document.body捕获${e.target.nodeName},当前对象为${e.currentTarget.nodeName}`)
  },true)
  div.addEventListener('click',(e)=>{
      console.log(`div捕获${e.target.nodeName},当前对象为${e.currentTarget.nodeName}`)
  },true)
  p.addEventListener('click',(e)=>{
      console.log(`p捕获${e.target.nodeName},当前对象为${e.currentTarget.nodeName}`)
  },true)
  span.addEventListener('click',(e)=>{
      console.log(`span捕获${e.target.nodeName},当前对象为${e.currentTarget.nodeName}`)
  },true)
  //当执行span的click是啊金输出结果为:
  <p>
window捕获SPAN,当前对象为undefined
document捕获SPAN,当前对象为#document
document.documentElement捕获SPAN,当前对象为HTML
document.body捕获SPAN,当前对象为BODY
div捕获SPAN,当前对象为DIV
p捕获SPAN,当前对象为P
span捕获SPAN,当前对象为SPAN
</p>
  //冒泡阶段
window.addEventListener('click',(e)=>{
      console.log(`window冒泡${e.target.nodeName},当前对象为${e.currentTarget.nodeName}`)
  },false)
  document.addEventListener('click',(e)=>{
      console.log(`document冒泡${e.target.nodeName},当前对象为${e.currentTarget.nodeName}`)
  },false)
  document.documentElement.addEventListener('click',(e)=>{
      console.log(`document.documentElement冒泡${e.target.nodeName},当前对象为${e.currentTarget.nodeName}`)
  },false)
  document.body.addEventListener('click',(e)=>{
      console.log(`document.body冒泡${e.target.nodeName},当前对象为${e.currentTarget.nodeName}`)
  },false)
  div.addEventListener('click',(e)=>{
      console.log(`div冒泡${e.target.nodeName},当前对象为${e.currentTarget.nodeName}`)
  },false)
  p.addEventListener('click',(e)=>{
      console.log(`p冒泡${e.target.nodeName},当前对象为${e.currentTarget.nodeName}`)
  },false)
  span.addEventListener('click',(e)=>{
      console.log(`span冒泡${e.target.nodeName},当前对象为${e.currentTarget.nodeName}`)
  },false)
  //当执行span的click是啊金输出结果为:
  <p>
span冒泡SPAN,当前对象为SPAN
p冒泡SPAN,当前对象为P
div冒泡SPAN,当前对象为DIV
document.body冒泡SPAN,当前对象为BODY
document.documentElement冒泡SPAN,当前对象为HTML
document冒泡SPAN,当前对象为#document
window冒泡SPAN,当前对象为
</p>

从上述输出结果可以清楚的看出是事件冒泡和事件冒泡的流程。
当然利用事件冒泡可以起到优化性能的作用(事件委托)
当鼠标点击li元素时,如果字体颜色为黑色就变成红色,如果是红色就变成黑色。
当点击li元素时,利用事件冒泡机制最终将冒泡到ul,因此直接将事件委托到ul父元素,而不需要给每个li元素添加事件。

//HTML
 <ul id="ul">
        <li>first</li>
        <li>second</li>  
        <li>third</li>
        <li>forth</li> 
    </ul>
//javascript
 window.onload = function(){
        let ul = document.getElementById('ul');
        ul.addEventListener('click',function(e){
            var e = window.event || e;
            if(e.target.nodeName.toLowerCase() == "li"){
                //alert( e.target.style.color)
               if(e.target.style.color == "black"){
                   e.target.style.color = "red";
               }else{
                   e.target.style.color = "black"
               }
            }
        },false)
    }

当然如果想阻止事件冒泡,可用的方法为:

 span.addEventListener('click',(e)=>{
        e.cancelBubble = true;
    },false)
或者
span.addEventListener('click',(e)=>{
        e.stopPropagation()
    },false)

猜你喜欢

转载自blog.csdn.net/GuoXiaoHong7758521/article/details/88878725