😄
前端学习
  • 👋Welcome
  • 📖前端基础
    • HTML
      • 基础知识
      • 进阶知识
      • HTML5
    • CSS
      • 基础知识
      • 进阶知识
      • CSS 专题
        • CSS 选择器
        • CSS 布局
        • CSS 动画
        • CSS 画图
        • 响应式方案
        • CSS BEM 规范
        • CSS 案例
    • JavaScript
      • 基础知识
      • 进阶知识
      • 常用内置对象
        • Array 对象
        • String 对象
        • Number 对象
        • Boolean 对象
        • Math 对象
        • Date 对象
        • RegExp 对象
        • Object 对象
      • JS 专题
        • 数据类型
        • 原型链/继承
        • 对象赋值与拷贝
        • this 的指向
        • 异步操作
        • 模块化
        • 设计模式
    • 浏览器
      • 浏览器模型
      • 事件
      • 位置属性
      • Web 缓存
      • 本地存储
    • 综合内容
      • 前端跨域
      • 登录鉴权
      • 文件上传与下载
  • 🏗️前端框架
    • Vue.js
      • 基础知识
      • Vue 组件通信
      • Vuex 使用指南
      • Vue 动画
      • 静态网站框架 VuePress
    • React.js
      • 基础知识
      • 组件通信
  • 📦计算机基础/后端
    • 图解计算机网络
    • HTTP/HTTPS
    • TCP/UDP
    • Node.js
    • MongoDB
  • 🛠️开发工具
    • 版本控制工具-Git
      • git submodule
    • 构建工具-Webpack
    • 错误监控工具-Sentry
    • 单元测试工具-Jest
    • 包管理工具-NPM
    • 代码编辑器-VSCode
  • 🤔专题内容
    • 前端工程化
    • 代码规范
      • JavaScript 代码规范
      • CSS 代码规范
      • Vue 代码规范
      • Git Commit 规范
      • 代码规范配置
    • 网络安全与防御
    • 性能优化
    • 算法编程
    • 数据可视化
  • 🧑‍💻 面试相关
    • 面试知识总结
    • 面试问题总结
    • 面试常见编程
    • 面试资源汇总
  • 🍭其他
    • 项目经验❗️
    • 踩坑指南❗️
      • JavaScript 踩坑指南
      • CSS 踩坑指南
      • Vue 踩坑指南
    • 学习资源
    • 综合收藏夹
由 GitBook 提供支持
在本页
  • 1. 事件传播
  • 2. 事件模型
  • 3. 事件代理

这有帮助吗?

  1. 前端基础
  2. 浏览器

事件

上一页浏览器模型下一页位置属性

最后更新于3年前

这有帮助吗?

事件就是文档或浏览器窗口中发生的一些特定的交互瞬间,其主要分为三步骤:

  1. 获取事件源(DOM元素)

  2. 绑定事件

  3. 设置事件驱动程序(即触发事件的处理)

获取事件源的方式:

  • document.getElementById();

  • document.getElementsByTagName();

  • document.getElementsByClassName();

  • document.querySelector(); //返回与该模式匹配的第一个元素

  • document.querySelectorAll() //返回与该模式匹配的所有元素

1. 事件传播

一个事件发生后,会在子元素和父元素之间传播(propagation)。这种传播分成三个阶段。

  • 第一阶段:从window对象传导到目标节点(上层传到底层),称为“捕获阶段”。

  • 第二阶段:在目标节点上触发,称为“目标阶段”。

  • 第三阶段:从目标节点传导回window对象(从底层传回上层),称为“冒泡阶段”。

// <div><p>点击</p></div>  - 分别为div和p添加捕获和冒泡阶段的函数,则点击的结果为:
// Tag: 'DIV'. EventPhase: 'capture'
// Tag: 'P'. EventPhase: 'target'
// Tag: 'P'. EventPhase: 'target'
// Tag: 'DIV'. EventPhase: 'bubble'
  1. 捕获阶段:事件从div向p传播时,触发div的捕获click事件;

  2. 目标阶段:事件从div到达p时,触发p的click冒泡事件;

  3. 冒泡阶段:事件从p传回div时,先触发p的捕获click事件,再次触发div的冒泡click事件。

不是所有的事件都能冒泡,以下事件不冒泡:blur、focus、load、unload、onmouseenter、onmouseleave。意思是,事件不会往父元素那里传递。

停止冒泡

addEventListener ****第三个函数表示监听函数是否在捕获阶段(capture)触发,默认 false,事件句柄在冒泡阶段执行,当设为 true 时,事件句柄在捕获阶段执行。

// 事件传播到 p 元素后,就不再向下传播了
p.addEventListener('click', function (event) {
  event.stopPropagation();
}, true);
​
// 事件冒泡到 p 元素后,就不再向上冒泡了
p.addEventListener('click', function (event) {
  event.stopPropagation();
}, false);
dom.onclick = function (event) {

    alert("child");

    // 阻止冒泡,IE10 以下则是 event.cancelBubble = true;
    event = event || window.event;

    if (event && event.stopPropagation) {
        event.stopPropagation();
    } else {
        event.cancelBubble = true;
    }
}

2. 事件模型

DOM0模型:DOM对象.事件 = 函数,一个元素的一个事件只能绑定一个响应函数,事件发生后不会传播,没有事件流概念<input type="button" onclick="func1()" />

var btn = document.getElementsByTagName("button")[0];

//这种事件绑定的方式,如果绑定多个,则后面的会覆盖掉前面的
btn.onclick = function (e) {
    console.log("事件1");
}

btn.onclick = function (e) {
    console.log("事件2");
}

IE事件模型:总共两个阶段事件处理阶段和事件冒泡阶段。绑定事件:attachEvent(eventType, handler);解除事件:detachEvent(eventType, handler)。

var btn = document.getElementsByTagName('button')[0];

btn.attachEvent('onclick', function(e) {
    console.log('事件1');
});

btn.attachEvent('onclick', function(e) {
    console.log('事件2');
});

DOM2模型*:总共三个阶段事件捕获阶段、事件处理阶段和事件冒泡阶段。

  • 绑定事件:ele.addEventListener(eventType, handler, useCapture);

  • 解除事件:ele.removeEventListener(eventType, handler, useCapture);

var btn = document.getElementsByTagName("button")[0];

btn.addEventListener("click", (e) => {});
btn.addEventListener("click", (e) => {});

3. 事件代理

由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件,通过判断事件发生元素DOM的类型,来做出不同的响应。这种方法叫做事件代理(delegation),也称事件委托。比较合适于动态元素的绑定。

var ul = document.querySelector('ul');
​
ul.addEventListener('click', function (event) {
  // 也可以写成这样 if(e.target && e.target.nodeName.toLowerCase() == "li")
  if (event.target.tagName.toLowerCase() === 'li') {
    // some code
  }
});

如果你对内容有任何疑问,欢迎提交 或

📖
❕issues
✉️ email