《WebKit 技术内幕》之五(4): HTML解释器和DOM 模型

4 影子(Shadow)DOM
        影子 DOM 是一个新东西,主要解决了一个文档中可能需要大量交互的多个 DOM 树建立和维护各自的功能边界的问题。

4.1 什么是影子 DOM
        当开发这样一个用户界面的控件——这个控件可能由一些 HTML 的标签元素组成,这些元素可以组成一颗 DOM 树的子树。这样一个 HTML 控件可以被到处使用,但是问题随之而来,那就是每个使用控件的地方都会知道这个子树的结构。 当网页的开发者需要访问网页 DOM 树的时候,这些控件内部的 DOM 子树都会暴露出来,这些暴露的节点不仅可能给 DOM 树的遍历带来很多麻烦,而且也可能给 CSS 的样式选择带来问题,因为选择器无意中可能会改变这些内部节点的样式,从而导致很奇怪的控件界面。

        如何将内部的节点信息封装起来,就像 C++ 语言的类一样,同时又能够将这些节点渲染出来呢 ? W3C 工作组提出的影子 DOM 概念。影子 DOM 的规范草案能够使得一些 DOM 节点在特定范围内可见,而在网页的 DOM 树中却不可见,但是网页渲染的结果中包含了这些节点,这就使得封装变得容易很多。

        下图描述了 HTML 文档对应的 DOM 树和 “div” 元素包含的一个影子 DOM 子树。当使用 JavaScript 代码访问 HTML 文档的 DOM 树的时候,通常的接口是不能直接访问到影子 DOM 子树中的节点的,JavaScript 代码只能通过特殊的接口方式。

        HTML5 支持了很多新的特性,例如对视频、音频的支持,读者会发现这些元素其实是由很复杂的控制界面组成,这些界面也是使用 HTML 元素编写,但是在 DOM 树中,你无法找到相应的节点,这其实也是使用了影子 DOM 的思想。

        因为影子 DOM 的子树在整个网页的 DOM 树中不可见,那么事件是如何处理的呢 ?事件中需要包含事件目标,这个目标当然不能是不可见的 DOM 节点,所以事件目标其实就是包含影子 DOM 子树的节点对象。事件捕获的逻辑没有发生变化,在影子 DOM 子树内也会继续传递。当影子 DOM 子树中的事件向上冒泡的时候, WebKit 会同时向整个文档的 DOM 上传递该事件,以避免一些很奇怪的行为。

4.2 WebKit 的支持
        WebKit 已经支持影子 DOM 的规范草案,虽然还存在一些问题。支持影子 DOM 的相关类在目录 “Source/core/dom/shadow” 下,里面的主要类是 ShadowRoot ,表示的是影子 DOM 的根节点。ShadowRoot 类继承自 DocumentFragment 类,所以它同样有 Node 节点的属性和方法,因而在影子 DOM 树的内部,遍历树没有什么特别不同的地方。

        当遍历 HTML 文档对应 DOM 树的时候,WebKit 需要做特别的判断,所以读者会发现在 WebKit 的 Node 类实现中存在大量的条件语句,用来检查当前节点是否是 ShadowRoot 对象,如果是该类的对象,把它作为不同 DOM 树之间的边界。有时候 WebKit 还需要对 ShadowRoot 对象作出特别处理,比如某些情况会略过它的子树,同样的,在事件处理的支持类 EventPathWalker 和 EventRetargeter 中,也需要做一些特别的处理逻辑,原理就是上面所述,细节不再介绍。

4.3 实践:使用影子 DOM
        示例代码 5-2 给出了一个简单的使用 webkitCreateShadowRoot 接口来创建影子 DOM 子树的例子。网页只包含了一个 “div” 元素,JavaScript 代码使用该元素创建了一个影子 DOM 子树的根节点,然后该根节点下加入了两个子女,第一个是图片元素,第二个是 “div” 元素,该元素内部包含了一些文本。

          打开 Chrome 浏览器的开发者工具,然后打开控制台,在其中输入 “document.firstChild.firstChild.nextElementSibling.firstElementChild.firstElementChild” 后会发现结果是空的,根据对应关系 “#document-> html -> head -> body -> div -> null”,虽然网页中没有 ‘head’ 元素,但是 DOM 树仍然会创建该节点。同时读者会发现 “div” 元素没有子女,影子 DOM 子树真的被隐藏起来了,成为真正的影子。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营29期|day 21 任务以及具体安排

530.二叉搜索树的最小绝对差 力扣题目链接(opens new window) 给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。 示例: 提示:树中至少有 2 个节点。 class Solution {TreeNode pre;// 记录上一个遍历的…

【C++笔记】C++11一些重要的新特性

一、列表初始化 C11第一个比较好用的特性就是”列表初始化",它可以大大的节省我们初始化对象的时间(特别是对象数组),虽然有些地方用起来有点儿奇怪,但是总的来说利大于弊。 1、列表初始化的使用方法 我们在使用C语言或者在C11之前&a…

对接苹果CMS芒果影视APPV1.0(附安装教程+源码支持多端)内置采集脚本

目录 概述1. 演示效果1.1 视频演示1.2 图文演示1.2.1 首页1.2.2 专题页1.2.3 搜索1.2.4 观影 2. 支持功能3. 插件和框架4. 部署方法4.1 后端4.1.1 准备工具4.1.2创建站点4.1.3 上传后端代码到服务器4.1.4 导入数据库4.1.5 配置数据库信息4.1.6访问后台管理系统 4.2 前端4.2.1 准…

新品发布 | 多通道总线记录仪TLog1004,是你期待的吗?

新品发布 2024年1月12日,同星智能又发布一款多通道 CAN (FD)总线、LIN 总线接口logger设备,此款产品在TLog1002基础上进行了升级,同时内置 3 路数字输入和 2 路数字输出,便于多种信号测量和系统集成。可以满…

企业招聘中怎么做才能通过性格测试

这是一个典型的话题,最近看了很多这方面话题,非常的具有代表性。 怎么做才能通过企业的性格测评呢? 这个问题没有标准答案,只能分类说明,并没有统一的规则和方法。 1、性格测试 性格测试主要是考量应聘者的性格特征…

【设计模式】什么是外观模式并给出例子!

什么是外观模式? 外观模式是一种结构型设计模式,主要用于为复杂系统、库或框架提供一种简化的接口。这种模式通过定义一个包含单个方法的高级接口,来隐藏系统的复杂性,使得对外的API变得简洁并易于使用。 为什么要使用外观模式&a…

互联网加竞赛 基于机器视觉的手势检测和识别算法

0 前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习的手势检测与识别算法 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng…

MySQL(五)——多表查询

上期文章 MySQL(四)——约束 文章目录 上期文章多表关系一对多(多对一)多对多多表外键关系可视化一对一 多表查询概述笛卡尔积多表查询分类连接查询 内连接隐式内连接显式内连接 外连接左外连接右外连接 自连接联合查询 union&am…

AWS 专题学习 P7 (FSx、SQS、SNS)

文章目录 Amazon FSx – 概述Amazon FSx for LustreFSx Lustre - 文件系统部署选项 Amazon FSx for NetApp ONTAPAmazon FSx for OpenZFSHybrid Cloud 存储AWS 存储云原生选项AWS 存储网关Amazon S3 File GatewayAmazon FSx File GatewayVolume GatewayTape GatewayStorage Gat…

虚幻UE 特效-Niagara特效实战-雨天

回顾Niagara特效基础知识:虚幻UE 特效-Niagara特效初识 其他两篇实战:虚幻UE 特效-Niagara特效实战-火焰、烛火、虚幻UE 特效-Niagara特效实战-烟雾、喷泉 本篇笔记我们再来实战雨天,雨天主要用到了特效中的事件。 文章目录 一、雨天1、创建雨…

Tortoise-orm 使用 (一) 创建表

项目基于Vue3.0, FastAPI的模板管理系统,从网上找了各种资源去实践,现在将总结发出来,分享给大家,希望帮助大家少走些弯路。 准备工作 # tortoise-orm pip install tortoise-orm # MySQL pip install tortoise-orm[asyncmy] # 迁…

DevExpress Web Report Designer中文教程 - 如何自定义控件和表达式注册?

获取DevExpress v23.2正式版下载(Q技术交流:909157416) 自定义控件集成 DevExpress Reports中的自定义报表控件注册变得更加容易,为了满足web开发人员的需求,DevExpressv23.1包括简化的自定义控件注册支持(在服务器级别实现)。如…