主要讲解事件绑定和事件委托,onclick事件和addEventListener的区别
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .father {
      width: 100%;
      height: 300px;
      display: flex;
    }
    .child {
      width: 100px;
      height: 100px;
      background-color: aquamarine;
      margin: 10px;
    }
  </style>
</head>
<body>
  <div class="father">
    <div class="child">1</div>
    <div class="child">2</div>
    <div class="child">3</div>
    <div class="child">4</div>
    <div class="child">5</div>
  </div>
</body>
</html>
示例1:给元素绑定click点击事件
 
使用onclick
 
- 重复绑定点击事件,后面的事件会覆盖前面的事件
<script>
  const element = document.querySelector('.father')
  element.onclick = () => {
    console.log('点击事件1')
  }
  element.onclick = () => {
    console.log('点击事件2')
  }
  // 控制台只会输出:点击事件2
</script>
使用addEventListener
 
- 重复绑定点击事件,事件不会被覆盖(类似于发布订阅模式,on中收集的事件存放在数组中,在emit时会遍历执行事件)
  <script>
    const element = document.querySelector('.father')
    element.addEventListener('click', () => {
      console.log('点击事件1')
    })
    element.addEventListener('click', () => {
      console.log('点击事件2')
    })
    // 控制台输出 点击事件1 点击事件2
  </script>
语法:document.addEventListener(event, function, useCapture)
 useCapture是可选的布尔值,指定事件是否在捕获或冒泡阶段执行
- true:事件在捕获阶段执行
- false:默认值,事件在冒泡阶段执行
element .addEventListener('click', (el) => {
  console.log(el.currentTarget) // 当前绑定事件的元素
  console.log(el.target) // 点击事件触发的元素
})
示例2:默认给每个child元素绑定一个点击事件,现在如果class名包含out-box的元素需要阻止之前绑定的点击事件
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .father {
      width: 100%;
      display: flex;
    }
    .child {
      width: 100px;
      height: 100px;
      background-color: aquamarine;
      margin: 10px;
    }
  </style>
</head>
<body>
  <div class="father">
    <div class="child">1
      <div class="bady-one">1-1
        <div class="yang-two">1-1-1</div>
      </div>
    </div>
    <div class="child">2
      <div class="bady-one out-box">2-1
        <div class="yang-two">2-1-1</div>
      </div>
    </div>
    <div class="child">3
      <div class="bady-one">3-1
        <div class="yang-two">3-1-1</div>
      </div>
    </div>
  </div>
  <script>
    // 示例:默认给每个child元素绑定一个点击事件,现在如果class名包含out-box的元素需要阻止之前绑定的点击事件
    const childElements = document.querySelectorAll('.child')
    childElements.forEach(el => {
      el.addEventListener('click', () => {
        console.log('child点击事件')
      })
    }) // 默认第三个参数为false,在冒泡阶段执行
  </script>
  <script>
	// 处理需求:在捕获阶段找到class名包含out-box的元素,并阻止冒泡
    const fatherElement = document.querySelector('.father')
    fatherElement.addEventListener('click', (el) => {
      const curentElement = el.target // 点击事件触发的元素,如果不是child元素,需要再找到它的class为child的父元素
      const parentElement = getParentElement(curentElement, 'child')
      if (curentElement.classList.toString().indexOf('child') !== -1 || parentElement) {
        if (curentElement?.querySelector('.out-box') || parentElement?.querySelector('.out-box')) {
          // console.log('点击事件')
          el.preventDefault() // 阻止默认行为
          el.stopPropagation() // 阻止冒泡
        }
      }
    }, true) // true点击事件在捕获阶段执行
    // 获取一个元素指定的父元素,使用元素的parentElement属性和while循环向上遍历DOM树,直到找到指定的父元素为止
    function getParentElement(target, className) {
      let parent = target.parentElement
      while (parent) {
        if (parent.classList.toString().indexOf(className) !== -1) {
          return parent
        }
        parent = parent.parentElement
      }
      return null
    }
  </script>
</body>
</html>
DOM事件流
 
 事件触发经典案例
 
解析:前面提到的DOM事件流的执行顺序是先捕获再冒泡,所以dom事件流从外向内捕获过程就是grandma -> monther -> daughter -> baby,而只有monther和daughter设置了useCapture = true,所以在捕获阶段就先将事件处理了,而grandma和baby并未设置useCapture = true,默认是false,而我们又是点击的baby所以首先会先处理baby目标事件,然后再通过冒泡到grandma事件。









![[强化学习]学习路线和关键词拾零](https://img-blog.csdnimg.cn/d38930816c1045968b03d2844d6bad8c.png)









