[TOC]

事件绑定

  1. image.png
  2. image.png

    事件冒泡

  3. 示例代码

image.png

<body>
  <div id="div1">
    <p id="p1">激活</p>
    <p id="p2">取消</p>
    <p id="p3">取消</p>
    <p id="p4">取消</p>
  </div>
  <div id="div2">
    <p id="p5">取消</p>
    <p id="p6">取消</p>
  </div>

  <script>
    function bindEvent (elem, type, fn) {
      elem.addEventListener(type, fn)
    }

    const p1 = document.getElementById('p1')
    const div1 =document.getElementById('div1')
    const body = document.body

    bindEvent(p1, 'click', e => {
      // e.stopPropagation();
      console.log('p1 clicked');
      console.log(e.target);
    })
    bindEvent(div1, 'click', e => {
      // e.stopPropagation();
      console.log('div1 clicked');
      console.log(e.target);
    })
    bindEvent(body, 'click', e => {
      console.log('body clicked');
      console.log(e.target);
    })
  </script>
</body>

事件代理

  1. 例如给多个a标签每个添加一个点击函数很麻烦,由于冒泡机制。会冒泡到父容器div上,那么就给div添加点击函数,这就是事件代理。
  2. 代码简洁、减少浏览器内存占用
  3. 但是不要滥用

    相关面试题

  4. 编写一个通用的事件监听函数

    // 通用的事件绑定函数,支持普通绑定和代理绑定
    function bindEvent (elem, type, selector, fn) {
    if (fn == null) {
     // 说明传入的是三个参数,两者互换
     fn = selector
     selector = null
    }
    elem.addEventListener(type, event => {
     const target = event.target
     if (selector) {
       // 代理绑定
       if (target.matches(selector)) {
         // 如果点击的目标是传入的选择器
         fn.call(target, event)
       }
     } else {
       // 普通绑定
       fn.call(target, event)
     }
    })
    }
    
  5. 描述事件冒泡的流程

    1. 基于DOM的树形结构
    2. 事件会顺着触发元素往上冒泡
    3. 应用场景:代理
  6. 无线下拉的图片列表,如何监听每个图片的点击?
    1. 使用事件代理 ```html
      a1
      a2
      a3
      a4

```