事件冒泡与事件捕获及事件委托

1.事件冒泡

事件冒泡:结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,即同一事件,自子元素冒泡向父元素。

关于事件的捕获与事件的冒泡过程图: 两者的顺序是先捕获后冒泡
在这里插入图片描述
事件冒泡就是在点击父盒子里面的元素的时候先先触发了子元素的事件,后触发父盒子的事件

 <div class="wrapper">
    <div class="content">
      <div class="box"></div>
    </div>
  </div>

  let wrapper = document.getElementsByClassName('wrapper')[0]
  let content = document.getElementsByClassName('content')[0]
  let box = document.getElementsByClassName('box')[0]
    // 冒泡
  wrapper.addEventListener('click',()=>console.log("wrapper1") ,false)
  content.addEventListener('click',()=>console.log("content1") ,false)
  box.addEventListener('click',()=>console.log("box1") ,false)

点击子元素box后的打印结果如下图,发生了事件冒泡
在这里插入图片描述

2.事件捕获

事件捕获:在谷歌浏览器上一个对象的一个事件类型只能存在一个事件模型
addEventListener的第三个参数把false变成true冒泡变成了捕获功能,父盒子先捕获事件,子盒子再捕获
结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获至子元素(事件源元素)

 <div class="wrapper">
    <div class="content">
      <div class="box"></div>
    </div>
  </div>

let wrapper = document.getElementsByClassName('wrapper')[0]
    let content = document.getElementsByClassName('content')[0]
    let box = document.getElementsByClassName('box')[0]

    // 捕获
    wrapper.addEventListener('click',()=>console.log("wrapper") ,true)
    content.addEventListener('click',()=>console.log("content") ,true)
    box.addEventListener('click',()=>console.log("box") ,true)

打印的顺序:
在这里插入图片描述
但是,当代码可以同时展现捕获和冒泡的时候

 wrapper.addEventListener('click',()=>console.log("wrapper") ,true)
    content.addEventListener('click',()=>console.log("content") ,true)
    box.addEventListener('click',()=>console.log("box") ,true)

    wrapper.addEventListener('click',()=>console.log("wrapper1") ,false)
    content.addEventListener('click',()=>console.log("content1") ,false)
    box.addEventListener('click',()=>console.log("box1") ,false)

就能看出顺序是先捕获后冒泡
在这里插入图片描述

讲讲this 掘金中的this

3.addEventListener

addEventListener是DOM2级事件新增的指定事件处理程序的操作,这个方法接收3个参数:要处理的事件名,作为事件处理程序的函数和一个布尔值,最后这个布尔值如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。
addEventListener第三个参数

4. 事件委托

利用事件冒泡,和事件源对象进行处理
优点:
1. 性能 不需要循环所有的元素一个个绑定事件
2. 灵活 当有新的子元素时不需要重新绑定事件

例子 点击li标签打印对应标签的内容
首要知识:事件对象 event 和事件源对象 event.target

<ul class="ul">
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
  </ul>
  //利用事件冒泡将子元素li的点击事件委托到父元素ul上 点击对应的li答应出li的内容
let ul = document.getElementsByClassName('ul')[0]
    ul.onclick = e => {
    
    
      console.log(e)
      console.log(e.target)
      console.log(e.target.innerText)
    }

补充

  • focus,blur,change,submit,reset,select 等事件不冒泡
  • 取消冒泡:
    W3C标准 event.stopPropagation();但不支持ie9以下版本
    IE独有 event.cancelBubble = true;
  • 阻止默认事件:
    默认事件 — 表单提交,a标签跳转,右键菜单等
    1.return false; 以对象属性的方式注册的事件才生效
    2.event.preventDefault(); W3C标注,IE9以下不兼容
    3.event.returnValue = false; 兼容IE

猜你喜欢

转载自blog.csdn.net/pz1021/article/details/105431358