Web Components系列(四) —— 认识 Shadow DOM

简介: 在初涉前端之时,我就一直在好奇一个问题,为什么像

0.png


前言


在初涉前端之时,我就一直在好奇一个问题,为什么像:


  • <input/>
  • <select></select>
  • <audio></audio>
  • <video></video>
  • ……


等等这些标签,看起来似乎很简单,可为什么可以展现出那么丰富复杂的布局?当时我给自己的解释是:这些标签都是系统控制渲染的。


现在想想,那么解释好像有点道理,但终归没有涉及到本质原因,专家级的解释应该是:以上这些元素都是以组件的方式存在,所展现出来的那些布局都是在组件内部定义好的,如果页面引用了这些元素标签,那它内部的布局都会渲染在页面上


在介绍 Web Components 时讲到,它的第二项技术规范为 Shadow DOM。通过了解 Shadow DOM 的相关知识,或许可以解开上面的疑惑。


查看默认组件的 Shadow DOM


有人可能疑惑,既然说文章开头列举的那些元素是组件,那为什么我在开发者工具中看到的结构是这样的:


1.png


有什么办法可以看到各个组件内部的 DOM 结构吗?答案是有的,步骤如下:


第一步:打开开发者工具,点击右上角的设置图标:


2.png


第二步:找到偏好设置-元素,然后对 “显示用户代理 Shadow DOM” 进行选中:


3.png


这时候,我们再查看那些默认组件的内部结构,如下所示:


4.png


可以看到,这些默认标签下都包含一个 “shadow root” 而在 shadow root 中包含的是具体布局:


5.png


一个看似简简单单的 audio 元素,里面的布局还蛮复杂的。这不禁让我想到一句话:功夫都在舞台外


在上面的截图中,我们看到了 “shadow root” ,它其实是 Shadow DOM 的一部分。


Shadow DOM  的概念


在介绍概念之前,我们先来看看 “shadow” 这个单词的中文释义:


6.png


Shadow DOM,翻译过来就是“影子 DOM” 。


影子当然都是藏在暗处,不容易让人发现的,就像文章开头提到的那些默认元素,如果不通过设置,我们表面上看到的就是简单的一个标签而已。


专业的解释就是:Shadow DOM 是 HTML 的一个规范 ,它允许浏览器开发者封装自己的HTML 标签、CSS 样式和特定的 Javascrip 代码,同时也可以让开发人员创建类似 <video> 这样的自定义标签。


Shadow DOM  的意义


“组件化”备受追捧的原因自然是因为它独特的魅力,我们只需要将定义好的组件通过简单的一组标签引入页面,就可以得到预定好的效果,并且可以在多处使用。


而 Shadow DOM 能在 Web Components 体系中占据重要的地位,是因为其具有良好的密封性,主要表现在:


  • 隐藏标记、样式和行为;
  • 保持代码隔离,保证页面的干净整洁,各组件内部代码互不影响;
  • 隐藏实现细节,便于使用更强大的语法或功能。


这就意味着,如果我们使用了 Shadow DOM,那就可以在它内部随意的发挥,而不必担心这些发挥会影响到页面的其他部分,变相地给了开发人员极大的自由。


想想曾经小心翼翼地定义样式、绑定事件的时光吧,怀念吗?


Shadow DOM 结构


Shadow DOM 允许将隐藏的 DOM 树附加到常规的 DOM 树中——它以 Shadow root 节点为起始根节点,在这个根节点的下方,可以是任意元素,和普通的 DOM 元素一样,借用网上的一张图片:


7.png


下面是我根据自己的理解画出来的:


8.png


大家根据自己喜好,看哪一张更容易理解就对着哪张看,都无所谓的。对应到实际的文档中,其结构如下:


9.png


在以上的结构图中,我们看到了几个陌生的名词,包括我们在之前看到的 “shadow root”,它们都是 Shadow DOM 的术语,接下来我解释一下它们各自的含义。


Shadow DOM 术语


Shadow host


一个常规 DOM节点,Shadow DOM 会被附加到这个节点上。


Shadow tree


Shadow DOM内部的DOM树。


Shadow boundary


Shadow DOM 分界线。Shadow DOM 结束的地方,也是常规 DOM 开始的地方。


Shadow root


Shadow tree 的根节点。


用法


挂载 Shadow DOM


可使用 Element.attachShadow()  方法给指定的元素挂载一个Shadow DOM,并且返回对 ShadowRoot 的引用。


let hostEle = document.getElementById("myCard");
let shadowroot = hostEle.attachShadow({mode: "open"});


控制 Shadow DOM


你可以使用同样的方式来操作 Shadow DOM,就和操作常规 DOM 一样——例如添加子节点、设置属性,以及为节点添加自己的样式(例如通过 element.style 属性),或者为整个 Shadow DOM 添加样式(例如在 <style> 元素内添加样式)。不同的是,Shadow DOM 内部的元素始终不会影响到它外部的元素(除了 :focus-within 元素内添加样式),这为封装提供了便利。


注意事项


如果一个元素底下已经有一个 Shadow DOM 挂载,继续给它挂载的话,会报错:


10.png


结束语


Shadow DOM 的主要作用就是其封装的特性,使得各组件的内部代码互不干扰,提供一个安全的开发运行环境。


关于 Shadow DOM 的基本概念就先介绍这么多,接下来将介绍它的操作方法。


~ 本文完,感谢阅读!


学习有趣的知识,结识有趣的朋友,塑造有趣的灵魂!




相关文章
|
2月前
|
XML 缓存 JavaScript
提升对前端的认知,不得不了解Web API的DOM和BOM
该文章强调了在前端开发中理解和掌握DOM(文档对象模型)和BOM(浏览器对象模型)的重要性,并介绍了它们的相关操作和应用。
提升对前端的认知,不得不了解Web API的DOM和BOM
|
3月前
|
XML JavaScript 前端开发
哇塞!Web 前端惊现 DOM 元素神操作,一场惊心动魄的网页变革,你准备好了吗?
【8月更文挑战第23天】在Web前端开发中,熟练操作DOM元素至关重要。DOM作为一种编程接口,将HTML/XML文档表示为节点树,便于使用JavaScript访问及修改文档内容与结构。
58 0
|
3月前
|
XML JavaScript 测试技术
Web自动化测试框架(基础篇)--HTML页面元素和DOM对象
本文为Web自动化测试入门指南,介绍了HTML页面元素和DOM对象的基础知识,以及如何使用Python中的Selenium WebDriver进行元素定位、操作和等待机制,旨在帮助初学者理解Web自动化测试中的关键概念和操作技巧。
54 1
|
4月前
|
JavaScript 前端开发 API
Web Components详解-HTML Templates
Web Components详解-HTML Templates
79 6
|
4月前
|
设计模式 JavaScript 前端开发
Web Components详解-组件通信
Web Components详解-组件通信
82 6
|
4月前
|
JavaScript 前端开发
Web Components详解-Shadow DOM样式控制
Web Components详解-Shadow DOM样式控制
139 3
|
4月前
|
JavaScript API 开发者
Web Components详解-Shadow DOM插槽
Web Components详解-Shadow DOM插槽
46 1
|
1月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
113 3
|
23天前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
125 45
|
4天前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
19 2