事件捕获和事件冒泡

557 阅读2分钟

这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战

前言

“八月的色彩是用金子铸就的,明亮而珍贵;八月的色彩是用阳光酿造的,芬芳而灿烂。”

未来的日子,愿你把自己调至最佳状态,缓缓努力,慢慢变好 Y(^o^)Y

事件

页面的 DOM 的元素构成了我们浏览器页面的静态元素,把对应的事件绑定到指定的 DOM 元素上,来反馈用户的行为操作。

我们可以说,事件就是当用户操作界面时,浏览器接受的一种特殊的可被浏览器识别的特殊指令。

我们所说的事件,基本上指的是 DOM 节点事件,常见就是 鼠标点击事件(click)、鼠标移动事件(mousemovemouseovermouseout mousedownmouseup

事件主要有三个阶段,我们称之为事件流,分别是事件捕获阶段处于目标阶段事件冒泡阶段

dom标准事件流的触发的先后顺序为:先捕获再冒泡,即当触发dom事件时,会先进行事件捕获,捕获到事件源之后通过事件传播进行事件冒泡。

所以事件发生在冒泡阶段

image.png

事件冒泡

当一个元素接收到事件的时候,会把他接收到的事件传给自己的父级,一直到window

阻止事件冒泡

  1. event.stopPropagation() 绑定的事件中直接使用

  2. window.event.cancelBubble = true 添加在addEventListener添加的事件中

import React, { useEffect } from 'react';

export default () => {
  useEffect(() => {

    const handle = () => {
      // 在原生事件中可以使用
      window.event.cancelBubble = true;
      console.log('click test element')
    }
    document.getElementById('test').addEventListener(
      'click',
      handle,
      false
    );

    return document.getElementById('test').removeEventListener('click', handle, false)
  }, []);

  const handleRoot = () => {
    console.log('click root element');
  };

  const handleParent = (e) => {
    console.log('click parent element');
  };
  const handleChild = (e) => {
    e.stopPropagation();
    console.log('click child element');
  };
  return (
    <React.Fragment>
      <h3>事件冒泡</h3>
      <div
        style={{ backgroundColor: '#eee', width: 400, height: 400 }}
        onClick={handleRoot}
      >
        <div
          style={{ backgroundColor: '#aaa', width: 300, height: 300 }}
          onClick={handleParent}
        >
          <div
            style={{ backgroundColor: 'blue', width: 150, height: 100 }}
            onClick={handleChild}
          ></div>

          <div
            style={{ backgroundColor: 'green', width: 150, height: 100 }}
            id="test"
          ></div>
        </div>
      </div>
    </React.Fragment>
  );
};

事件捕获

事件从最不精确的对象(document 对象)开始触发,然后依次将事件传给子级,跟冒泡的顺序相反

事件委托

它还有一个名字叫事件代理,JavaScript高级程序设计上讲:

事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

html:

<ul id="ul">
   <li>1</li>
   <li>2</li>
   <li>3</li>
</ul>

js:

document.getElementById('ul').addEventListener('click', function (e) {
        console.log(e.target.tagName.toLowerCase());

        if(e.target.tagName.toLowerCase() === 'li'){
            console.log(e.target.innerHTML);
        }
    }, false); 

点击<li>1</li>,打印的结果是:li 1

点击<li>2</li>,打印的结果是:li 2

点击<li>3</li>,打印的结果是:li 3

我们并没有给li绑定任何事件,但是我们点击li却能产生效果,这其实就是应用了我们前面所讲的事件冒泡或者事件捕获。 当我们点击li时,通过冒泡原理,会将点击事件传递给他的父级ul,然后运行ul上面所绑定的function,并把li的事件委托给ul所绑定的这个function执行。

结语

如果这篇文章帮到了你,欢迎点赞👍和关注⭐️

文章如有错误之处,希望在评论区指正🙏🙏。