《WebKit 技术内幕》之五(3): HTML解释器和DOM 模型
3 DOM的事件机制
基于 WebKit 的浏览器事件处理过程:首先检测事件发生处的元素有无监听者,如果网页的相关节点注册了事件的监听者则浏览器会将事件派发给 WebKit 内核来处理。另外浏览器可能也需要处理这样的事件(浏览器对于有些事件必须响应从而做出默认处理,比如通过鼠标滚轮来翻滚网页,鼠标所在位置的 HTML 元素上注册了滚动事件监听器)。事件到达 WebKit 内核即渲染引擎接收到一个事件后,会先检查那个元素是直接的事件目标,然后会经过自顶向下和自底向上的过程。
3.1 事件的工作过程
事件在工作过程中使用两个主体,第一个是事件(event),第二个是事件目标(EventTarget)。WebKit 中用 EventTarget 类来表示 DOM 规范中 Events 部分定义的事件目标。
每个 事件都有属性来标记该事件的事件目标。当事件到达事件目标(如一个元素节点)的时候,在这个目标上注册的监听者(Event Listeners)都会有触发调用,而这些监听者的调用顺序不是固定的,所以不能依赖监听者注册的顺序来决定你的代码逻辑。
DOM标准对EventTarget 接口的定义。下图中的接口是用来注册和移除监听者的。

事件处理最重要就是事件捕获(Event capture)和事件冒泡(Event bubbling)这两种机制。下图是事件捕获和事件冒泡的过程。

当渲染引擎接收到一个事件的时候,它会通过 HitTest(WebKit 中的一种检查触发gkwrd哪个区域的算法)检查哪个元素是直接的事件目标。在上图 中,以 “img” 为例,假设它是事件的直接目标,这样,事件会经过自顶向下和自底向上的两个过程。
事件的捕获是自顶向下,事件先是到 document 节点,然后一路到达目标节点。在上图 中,顺序就是 “#document” -> “HTML” -> “body” -> “img” 这样一个顺序。事件可以在这一传递过程中被捕获,只需要在注册监听者的时候设置相应参数即可。在前面的接口图中的接口add Event L istener的第三个参数就是表示这个含义。默认情况下,其他节点不捕获这样的事件。如果网页注册了这样的监听者,那么监听者的回调函数会被调用,函数可以通过事件的 “stopPropagation” 函数来阻止事件向下传递。
事件的冒泡过程是从下向上的顺序,它的默认行为是不冒泡,但是是事件包含一个是否冒泡的属性。当这一属性为真的时候,渲染引擎会将该事件首先传递给事件的目标节点的父亲,然后是父亲的父亲,以此类推。同捕获动作一样,这此监听函数也可以使用 “stopPropagation” 函数来阻止事件向上传递。
3.2 WebKit 的事件处理机制
DOM 的事件分为很多种,与用户相关的只是其中的一种,称为 UIEvent ,其他的包括 CustomEvent、MutationEvent 等。UIEvent 又可以分为很多种,包括但是不限于 FocusEvent、MouseEvent、KeyboardEvent、Composition 等。
基于 WebKit 的浏览器事件处理过程,首先是做 HitTest ,查找事件发生处的元素,检查该元素有无监听者。如果网页的相关节点注册了事件的监听者,那么浏览器会把事件派发给 WebKit 内核来处理。同时,浏览器也可能需要理解和处理这样的事件。这主要是因为,有些事件浏览器必须响应从而对网页作默认处理。

图中黑色圆形表示光标的当前位置,光标下面的元素注册了一个监听鼠标滚轮事件的函数,当用户滚动鼠标的时候,浏览器经过HitTest之后,发现有监听者,它需要将这些事件传递给WebKit,WebKit实际上最后调用JavaScript引擎来触发监听者函数。但是,浏览器可能也会根据这些事件仍然处理它的默认行为,这会导致竞争冲突,所以Web开发者在监听者的代码中应该调用事件的preventDefault函数来阻止浏览器触发它的默认处理行为,也就是不需要滚动整个网页。
当事件的派发机制遇到网页的框结构特别是多框结构的时候,情况变得稍显复杂,这是因为事件需要在多个框和多个DOM树之间传递。当触控事件(Touch Events)被引入后情况变得更为复杂。
下图 简单描述了鼠标事件的调用过程,这一过程本身是比较简单的,复杂之处在于 WebKit 的 EventHandler 类。

EventHandler 类是处理事件的核心类,它除了需要将各种事件传给 JavaScript 引擎以调用响应的监听者之外,它还会识别鼠标事件,来触发调用右键菜单、拖放效果等与事件密切相关的工作,而且 EventHandler 类还支持网页的多框结构。EventHandler 类的接口比较容易理解,但是它的处理逻辑极其复杂。
WebKit 中还有些跟事件处理相关的其他类,例如 EventPathWalker、EventDispatcher 类等,这些类都是为了解决事件在 DOM 树中传递的问题。
相关文章:
《WebKit 技术内幕》之五(3): HTML解释器和DOM 模型
3 DOM的事件机制 基于 WebKit 的浏览器事件处理过程:首先检测事件发生处的元素有无监听者,如果网页的相关节点注册了事件的监听者则浏览器会将事件派发给 WebKit 内核来处理。另外浏览器可能也需要处理这样的事件(浏览器对于有些事件必须响应…...
136基于matlab的自适应滤波算法的通信系统中微弱信号检测程序
基于matlab的自适应滤波算法的通信系统中微弱信号检测程序,周期信号加入随机噪声,进行滤波,输出滤波信号,程序已调通,可直接运行。 136 matlab自适应滤波算法LMS (xiaohongshu.com)...
【Linux】权限 !
Linux 权限 Liunx Linux 权限1 什么是权限1.1 Linux用户1.2 切换用户 2 权限管理2.1 文件访问者的分类2.2 文件类型和访问权限2.3 文件权限的设置方法chmod 命令chown 命令chgrp 命令umask 命令file 指令 2.4 目录权限粘滞位 3 权限总结 1 什么是权限 关于Linux的权限问题&…...
axios原理
文章目录 axios基本概念axios多种方式调用工具函数axios的拦截器如何实现?用的设计模式是哪种?axios如何实现取消请求,和cancelToken如何使用 axios基本概念 axios是目前比较流行的一个js库,是一个基于promise的网络数据请求库&am…...
epoll
常用函数 //创建 /** * param size 告诉内核监听的数目 * * returns 返回一个epoll句柄(即一个文件描述符) */ int epoll_create(int size);//控制 /** * param epfd 用epoll_create所创建的epoll句柄 * param op 表示对epoll监控描述符控制的动作 * * …...
AEB滤镜再破碎,安全焦虑「解不开」?
不久前,理想L7重大交通事故,再次引发了公众对AEB的热议。 根据理想汽车公布的事故视频显示,碰撞发生前3秒,车速在178km/h时驾驶员采取了制动措施,但车速大幅超出AEB(自动紧急刹车系统)的工作范…...
深度学习和机器学习中针对非时间序列的回归任务,有哪些改进角度?
深度学习和机器学习中针对非时间序列的回归任务,有哪些改进角度? 目录 深度学习和机器学习中针对非时间序列的回归任务,有哪些改进角度?引言1 数据预处理2 数据集增强3 特征选择4 模型选择5 模型正则化与泛化6 优化器7 学习率8 超…...
无限商机、拓全国、赢未来!2024上海国际轴承展重磅来袭!
中国设备管理协会主办的“2024上海国际轴承及其专用装备展览会”将于2024年7月24日至26日在“国家会展中心(虹桥)”举办。展会预计展出面积55000平方米,汇聚来自世界各地的近1000家企业与60000多人次的国内外观众齐聚一堂。为期三天的展览会是…...
PPT 编辑模式滚动页面不居中
PPT 编辑模式滚动页面不居中 目标:编辑模式下适应窗口大小、切换页面居中显示 调整视图大小,编辑模式通过Ctrl 鼠标滚轮 或 在视图菜单中点击适应窗口大小。 2. 翻页异常,调整视图大小后,PPT翻页但内容不居中或滚动,…...
笨蛋学设计模式结构型模式-享元模式【13】
结构型模式-享元模式 7.7享元模式7.7.1概念7.7.2场景7.7.3优势 / 劣势7.7.4享元模式可分为7.7.5享元模式7.7.6实战7.7.6.1题目描述7.7.6.2输入描述7.7.6.3输出描述7.7.6.4代码 8.1.7总结享元模式 7.7享元模式 7.7.1概念 享元模式是通过共享对象减少内存使用,来…...
磁盘的分区与文件系统的认识
磁盘的认识 了解磁盘的结构: 1、盘片 硬盘首先会有多个盘片构成,类似很多个独立的光盘合并在一起,每个盘片都有2个面,每个盘片都有一个对应的磁头,我们的磁头横移和盘面的旋转就可以读写到盘面的每一个位置,…...
韩国访问学者如何申请?
作为访问学者,前往韩国学术机构进行研究是一项令人期待的经历。首先,申请者需要查找目标学术机构的官方网站,下面知识人网小编带大家了解其访问学者计划的具体要求和申请流程。 通常,申请程序包括填写在线申请表格,提交…...
MybatisPlus框架入门级理解
MybatisPlus 快速入门入门案例常见注解常用配置 核心功能条件构造器自定义SQLService接口 快速入门 入门案例 使用MybatisPlus的基本步骤: 1.引入MybatisPlus的起步依赖 MybatisPlus官方提供了starter,其中集成了Mybatis和MybatisPlus的所有功能&#…...
ELK 分离式日志(1)
目录 一.ELK组件 ElasticSearch: Kiabana: Logstash: 可以添加的其它组件: ELK 的工作原理: 二.部署ELK 节点都设置Java环境: 每台都可以部署 Elasticsearch 软件: 修改elasticsearch主配置文件&…...
<蓝桥杯软件赛>零基础备赛20周--第15周--快速幂+素数
报名明年4月蓝桥杯软件赛的同学们,如果你是大一零基础,目前懵懂中,不知该怎么办,可以看看本博客系列:备赛20周合集 20周的完整安排请点击:20周计划 每周发1个博客,共20周。 在QQ群上交流答疑&am…...
Opencv小项目——手势数字刷TIKTOK
写在前面: 很久没更新了,之前的实习的记录也算是烂尾了,但是好在自己的实习记录还是有的,最近也忙碌了很多,终于放假了,今天下午正好没事,闲来无事就随便做个小玩意吧。 思来想去ÿ…...
【优化技术专题】「性能优化系列」针对Java对象压缩及序列化技术的探索之路
针对Java对象压缩及序列化技术的探索之路 序列化和反序列化为何需要有序列化呢?Java实现序列化的方式二进制格式 指定语言层级二进制格式 跨语言层级JSON 格式化类JSON格式化:XML文件格式化 序列化的分类在速度的对比上一般有如下规律:Java…...
Spring+SprinMVC+MyBatis配置方式简易模板
SpringSprinMVCMyBatis配置方式简易模板代码Demo GitHub访问 ssm-tpl-cfg 一、SQL数据准备 创建数据库test,执行下方SQL创建表ssm-tpl-cfg /*Navicat Premium Data TransferSource Server : 127.0.0.1Source Server Type : MySQLSource Server Versio…...
Windows ssh登录eNSP交换机
目录 1. Cloud IO配置1.1 创建UDP端口1.2 创建本地连接1.3 端口映射设置 2. 交换机配置2.1 配置vlanif2.2 配置vty2.3 配置ssh用户2.4 配置aaa2.5 使用Xshell工具登录2.6 用户和密码2.7 登录成功 3. 使用cmd 登录报错提示3.1 手动指定加密算法,提示密码长度无效3.2 …...
SwiftUI 纯手工打造 100% 可定制的导航栏
功能需求 何曾几时,我们是否也厌倦了 SwiftUI 界面中刻板守旧的导航栏外观,而想要自己动手充分展示灵动炸裂的创造力呢? 如上图所示:我们在 SwiftUI 中通过纯手工打造了一款 100 在本篇博文中,您将学到以下内容 功能需求1. 导航栏基本结构2. 如何感知当前发生用户拖拽行为…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
