《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 树中传递的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/340756.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

BGP Local-preferenct 、AS-Path、 Origin 综合选路实验

Local-preference: 本地优先级,公认任意,仅能在 AS 内使用(IBGP内传递),不能在EBGP传递,默认值 100,越大越优。用于离开本 AS ,在 IBGP 的入、出方向都可使用&#xff0c…

双端Diff算法

双端Diff算法 双端Diff算法指的是,在新旧两组子节点的四个端点之间分别进行比较,并试图找到可复用的节点。相比简单Diff算法,双端Diff算法的优势在于,对于同样的更新场景,执行的DOM移动操作次数更少。 简单 Diff 算法…

光学期刊1

光学领域的你,如何评价最近发布的光学期刊分区? 如题,附分区表 20240122 知乎 同样先写结论:时代变了,发国产没错的。参考light当年开局多艰难,被各种diss口碑差,很多投一区守门员不中的也…

二进制部署高可用k8s集群V1.20.11版本

文章目录 一、操作系统初始化配置(所有节点均执行)1、关闭防火墙2、关闭selinux3、关闭swap4、根据规划修改主机名5、在master节点上添加host6、将桥接的IPv4流量传递到iptables的链7、时间同步 二、部署Etcd集群1、准备cfssl证书生成工具2、生成Etcd证书…

2024年软件测试面试题大全【含答案】

Part1 1、你的测试职业发展是什么?【文末有面试文档免费领取】 测试经验越多,测试能力越高。所以我的职业发展是需要时间积累的,一步步向着高级测试工程师奔去。而且我也有初步的职业规划,前3年积累测试经验,按如何做…

tableau mysql 驱动安装

最便捷,最快速的方式。 整体流程:首先得知道你电脑mysql的版本,然后去官网下载ODBC驱动。 mysql版本:浏览器搜一些。 高版本驱动应该是兼容低版本的。 ODBC驱动: 选择第一个,下载,直接msi安装…

学习笔记之 机器学习之预测雾霾

文章目录 Encoder-DecoderSeq2Seq (序列到序列) Encoder-Decoder 基础的Encoder-Decoder是存在很多弊端的,最大的问题就是信息丢失。Encoder将输入编码为固定大小的向量的过程实际上是一个“信息有损的压缩过程”,如果信息量越大,…

POKT Network (POKT) :进军百亿美元市场规模的人工智能推理市场

POKT Network(又称 Pocket Network)是一个去中心化的物理基础设施网络(DePIN),它能够协调并激励对任何开放数据源的访问,最初专注于向应用程序和服务提供商提供区块链数据。 自 2020 年主网上线以来&#x…

MSG3D

论文在stgcn与sta-lstm基础上做的。下面讲一下里面的方法: 1.准备工作 符号。这里是对符号进行解释。 一个人体骨骼图被记为G(v,E) 图卷积: 图卷积定义 考虑一种常用于处理图像的标准卷积神经网络 (CNN)。输入是像素网格。每个像素都有一个数据值向…

大数据开发之电商数仓(hadoop、flume、hive、hdfs、zookeeper、kafka)

第 1 章:数据仓库 1.1 数据仓库概述 1.1.1 数据仓库概念 1、数据仓库概念: 为企业制定决策,提供数据支持的集合。通过对数据仓库中数据的分析,可以帮助企业,改进业务流程、控制成本,提高产品质量。 数据…

网络:FTP

1. FTP 文件传输协议,FTP是用来传输文件的协议。使用FTP实现远程文件传输的同时,还可以保证数据传输的可靠性和高效性。 2. 特点 明文传输。 作用:可以从服务器上下载文件,或将本地文件上传到服务器。 3. FTP原理 FTP有控制层面…

Java技术栈 —— JVM虚拟机

JVM虚拟机 一、字节码(Byte-Code)1.1 如何查看字节码?1.2 如何理解字节码的作用? 二、JVM内存模型(极其重点,必须牢牢把握住)2.1 方法区2.2 虚拟机栈2.3 本地方法栈2.4 堆2.5 程序计数器2.6 面试必问 三、GC机制四、JV…

【华为 ICT HCIA eNSP 习题汇总】——题目集7

1、一台 PC 的 MAC 地址是 5489-98FB-65D8 ,管理员希望该 PC 从 DHCP 服务器获得指定的 IP 地址为192.168.1.11/24,以下命令配置正确的是()。 A、dhcp static-bind ip-address 192.168.1.11 24 mac- address 5489-98FB-65D8 B、dh…

力扣740. 删除并获得点数

动态规划 思路: 选择元素 x,获得其点数,删除 x 1 和 x - 1,则其他的 x 的点数也会被获得;可以将数组转换成一个有序 map,key 为 x, value 为对应所有 x 的和;则问题转换成了不能同…

中间件-缓存、索引、日志

文章目录 缓存中间件本地缓存中间件分布式缓存中间件全文索引中间件分布式日志中间件小结 缓存中间件 缓存是性能优化的一大利器 我们先一起来看一个用户中心查询用户信息的基本流程 这时候,如果查找用户信息这个 API 的调用频率增加,并且在整个业务流…

怎么使用【jmeter正则表达式提取器】解决返回值作参数的问题

前言 我们在使用jmeter做接口测试时,常常会碰到上个接口的返回值会作为下个接口的参数来进行请求。这时候,就需要用到jmeter的正则表达式提取器了。 添加正则表达式提取器步骤: “选择要添加提取器的接口右键”——add——post processors—…

线程池--JAVA

虽然线程是轻量级进程,但是如果当创建和销毁的的频率非常之高,那么它也就会消耗很多的资源。 而线程池就是用来优化线程频繁创建和销毁的场景,减少线程创建、销毁的频率。 ExecutorService JAVA标准库为我们实现了线程池,Execu…

archlinux 如何解决安装以后没有声音的问题

今天安装完archlinux以后发现看视频没声音 检查一下是否有 /lib/firmware/intel/sof 发现没有 如果你也是这样的话,可以尝试安装: sudo pacman -S sof-firmware 重启后再看看有没有声音: reboot 反正我有声音了

跟着我学Python进阶篇:03. 面向对象(下)

往期文章 跟着我学Python基础篇:01.初露端倪 跟着我学Python基础篇:02.数字与字符串编程 跟着我学Python基础篇:03.选择结构 跟着我学Python基础篇:04.循环 跟着我学Python基础篇:05.函数 跟着我学Python基础篇&#…

【ARM 嵌入式 编译系列 7.3 -- GCC 链接脚本中 DISCARD 与 .ARM.exidx】

请阅读【嵌入式开发学习必备专栏 之 ARM GCC 编译专栏】 文章目录 背景.ARM.exidx方法一:使用链接器脚本方法二:使用链接器选项注意事项背景 在移植 RT-Thread 到 cortex-m33(RA4M2)上的时候,在编译的时候遇到下面问题: Building target: ra4m2.elf arm