说到 shadow-dom 可能很多人会很陌生。但是其实我们肯定碰到过,本文主要想简单介绍下 shadow-dom。下面直接进入正文。

shadow-dom 是什么

顾名思义, shadow-dom,直译的话就是 影子dom ?我觉得可以理解为潜藏在黑暗中的 DOM 结构,也就是我们无法直接控制操纵的 DOM 结构。前端同学经常用开发者工具的话,查看 DOM 结构的时候,肯定看到过下面这样的结构:

这里的 #shadow-root 所包含的内容其实就是所谓的 shadow-dom

shadow-dom 其实是浏览器的一种能力,它允许在浏览器渲染文档(document)的时候向其中的 Dom 结构中插入一棵 DOM 元素子树,但是特殊的是,这棵子树(shadow-dom)并不在主 DOM 树中。

举个栗子,也是最常见的例子, <video> 标签,我们创建在页面上创建一个空白的 video 标签:

?
1
<video id='test'></video>

查看 DOM 结构如下:

虽然我们创建的是一个空标签,但是在这个空标签内部,存在一个 shadow-dom ,点开 shadow-dom 可以看到内有乾坤,大有内容。其实这内部的具体内容,就是 <video> 的具体实现。

shadow-dom 结构示意

再用一幅图总结一下:

document

这个很好理解,就是我们的正常文档 document 。

shadow host

对于一个内部有 shadow-dom 的元素而言,它必然需要一个宿主元素,对于上面的例子而言, <video> 标签,就是 shadow-dom 的宿主元素。

shadow-root

通过 createShadowRoot(下文会提及) 返回的文档片段被称为 shadow-root 。它和它的后代元素,都将对用户隐藏,但是它们是实际存在的,在 chrome 中,我们可以通常审查元素去查看它们的具体 DOM 实现。

<video> 中,例如暂停,播放,音量控制,全屏按钮,进度条等都是 shadow-root 的后代。它们工作时会显示在屏幕上,但他们的 DOM 结构对用户是不可见的。

contents

就是上述所说的 <video> 中各子组件的 DOM 的具体实现。

为什么需要 shadow-dom

为什么需要有这种结构呢?

Shadow-dom 是游离在 DOM 树之外的节点树,但是他的创建基于普通 DOM 元素(非 document),并且创建后的 Shadow-dom 节点可以从界面上直观的看到。更重要的是,Shadow-dom 具有良好的密封性。

这是浏览器提供的一种“封装”功能,提供了一种强大的技术去隐藏一些实现细节。什么意思呢?以 w3c 上的一个 <video> 例子为例,我们仅仅是填写了一个空白的标签,再加上 src 属性里填上视频地址,就可以播放视频了:

我们仅仅填写了一行代码,却拥有比这行代码更多的功能,譬如暂停,播放,音量控制,全屏按钮,进度条等等。

这些功能具体的 DOM 实现,其实都在 shadow-dom 中:

浏览器的开发者们意识到作为前端开发者,引用一个 <video> 标签的时候,每次还要写入一大堆 DOM 去控制控件的表现和行为,既不简洁也很困难。所以他们界定了这样一个界限,界定了哪些是你可以访问的,哪些实现细节是访问不到的。

那些不希望我们访问到的细节,则封装在了 shadow-dom 中。然而,浏览器本身却可以随意跨越这个边界。设置这样一个边界之后,浏览器的开发者们就可以在我们看不见的地方使用熟悉的web技术、同样的HTML元素去创建更多的功能,而不是像我们一样要在页面上用div和span来堆砌这些元素。

如何控制 shadow-dom

既然是浏览器开发者有意隐藏起来的 DOM 结构,那么我们是否可以控制内部的 DOM 结构呢?并非完全不可以,还是有一些方法使得我们可以控制 shadow-dom 内的一些表现。

使用伪元素控制 shadow-dom 样式

这里我们要使用到伪元素,通过伪元素,我们可以控制 shadow-dom 中 DOM 结构的样式。

在 chrome 下,查看 shadow-dom 结构(如果无法看到shadow-dom需要手动打开),可以看到每个结点都加上了一个 pesudo 属性:

有了这些属性,我们可以通过伪元素的方式控制他们,譬如在一些场景下 video 标签的控制条不会自动隐藏或自动显示,可以通过伪元素指定默认显隐方式:

如果你在 chrome 浏览器下阅读本文,从上面的 codePen 可以看到,我使用伪元素修改了 video 控件条的底色为粉红色 deeppink。

不幸的是,上面的控制方式只适用于 chrome 浏览器,虽然大部分现代浏览器已经支持 shadow-dom ,但是能够审查 shadow-dom 内部 DOM 元素的只有 chrome 浏览器,其他浏览器仍会把这些细节隐藏。

使用 Javascript 创建一个 shadow-dom 元素

我们也可以通常 Javascript 创建 shadow-dom ,实现各类功能的封装,主要通过:

?
1
2
3
4
HTMLElement.prototype.createShadowRoot =
HTMLElement.prototype.createShadowRoot ||
HTMLElement.prototype.webkitCreateShadowRoot ||
function() {};

看看下面这个例子,在chrome内核浏览器下,将创建一个简单的 shadow-dom ,将我们的代码放入一个template 中,再通过 importNode 插入到 shadow-dom 中:

如果你现在在 chrome 内核浏览器下访问本文,那么上述的 codePen 中你应该可以看到 createShadowDomByJs 这一行文字,打开审查元素,会看到 <p> 结构是隐藏在 shadow-dom 中的。

shadow-dom 兼容性

shadow-dom 的未来

本文是非常基本的一些关于 shadow-dom 的概念,只是它的冰山一角,没有十分深入的去研究。

现行的组件都是开放式的,即最终生成的 HTML DOM 结构难以与组件外部的 DOM 进行有效结构区分,样式容易互相混淆。Shadow-dom 的 封装隐藏性为我们提供了解决这些问题的方法。在 Web 组件化的规范中也可以看到 Shadow-dom 的身影,使用具有良好密封性的 Shadow-dom 开发下一代 Web 组件将会是一种趋势。

更多资源及参考文章

如果你读完本文后仍然意犹未尽,可以看看下面这些文章:

  • Introduction to Shadow DOM
  • A Guide to Web Components
  • Shadow DOM 201
  • [译]什么是Shadow Dom?

到此本文结束,如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

http://www.cnblogs.com/coco1s/p/5711795.html

神秘的 shadow-dom 浅析相关推荐

  1. shadow dom一个最简单的例子

    本文资料来自stackoverflow:https://stackoverflow.com/questions/34119639/what-is-shadow-root/34119775#341197 ...

  2. html页面和Chrome开发者工具elements界面不一致的一个可能原因:没有在Chrome开发者工具里打开对Shadow DOM显示的支持

    一个例子: 虽然UI上input field里显示的是Jerry,但是Chrome开发者工具里面并没有显示出来. 注意上图最下方,显示的input后面有#shadow-root.div. 打开sett ...

  3. 理解Shadow DOM

    1. 什么是Shadow DOM? Shadow DOM 如果按照英文翻译的话可以理解为 影子DOM, 何为影子DOM呢?可以理解为一般情况下使用肉眼看不到的DOM结构,那如果一般情况下看不到的话,那 ...

  4. [译] 用 Shadow DOM v1 和 Custom Elements v1 实现一个原生 Web Component

    原文地址:Make a Native Web Component with Custom Elements v1 and Shadow DOM v1 原文作者:Pearl Latteier 译文出自: ...

  5. Shadow DOM及自定义标签

    参考链接:点我 一.什么是Shadow DOM Shadow DOM,直接翻译的话就是 影子 DOM,可以理解为潜藏在 DOM 结构中并且我们无法直接控制操纵的 DOM 结构.类似于下面这种结构 Sh ...

  6. [html] 举例说明Shadow DOM的应用场景有哪些?

    [html] 举例说明Shadow DOM的应用场景有哪些? 可以将 shadow DOM 视为"DOM中的DOM".它是自己独立的DOM树,具有自己的元素和样式,与原始DOM完全 ...

  7. [html] 说说你对影子(Shadow)DOM的了解

    [html] 说说你对影子(Shadow)DOM的了解 web component的API,用来给组件创建子DOM树,就像楼上说的,不受外部style影响,外部通过选择器查询也不会查到里面来.它有两种 ...

  8. Shadow DOM的理解

    Shadow DOM的理解 Shadow DOM是HTML的一个规范,其允许在文档document渲染时插入一颗DOM元素子树,但是这棵子树不在主DOM树中,Shadow DOM如果按照英文翻译的话可 ...

  9. 纯CSS菜单样式,及其Shadow DOM,Json接口 实现

    先声明,要看懂这篇博客要求你具备少量基础CSS知识, 当然如果你只是要用的话就随便了,不用了解任何知识 先放一张效果图         Part 1:纯CSS菜单样式 先放样式代码 1 <sty ...

  10. Shadow DOM系列1-简介

    为什么80%的码农都做不了架构师?>>>    英文链接:Shadow DOM: Introduction, 26 AUGUST 2013 on Web Components, Sh ...

最新文章

  1. IoU、GIoU、DIoU、CIoU损失函数
  2. 两台电脑cpu序列号一样_如何正确使用苹果电脑?
  3. 向maven中央仓库提交jar
  4. BeetleX.FastHttpApi之JWT和自定义访问验证
  5. Base64编码的原理与常用实现
  6. img标签里的value获取
  7. (129)FPGA面试题-FPGA前仿真与后仿真的区别?
  8. 美团饿了吗外卖小程序CPS红包推广源码+可编译H5
  9. Springboot实现多数据源整合的两种方式
  10. deepin删除应用程序中图标
  11. python画狗的代码_简单的Python代码能狗实现哪些丧心病狂的功能
  12. JavaFX开发教程——快速入门FX
  13. MySQL数据库的存储引擎
  14. 计算机考研公共课考英语几,新文道教育:2022考研必须要了解的30个知识点
  15. 【开发日记】马桶型号识别
  16. NKOI 2495 火车运输
  17. pytorch深度学习简介(包括cnn,rnn等我只挑我感觉有必要记录)
  18. 视频播放+详情页+购物车
  19. MAMP 修改数据库密码
  20. 赛博朋克 “故障风”按钮

热门文章

  1. paip. c++ doxygen 文档工具的使用以及跟QT CREATOR的集成
  2. ECLIPSE远程调试TOMCAT.
  3. 基金行业数据安全保障体系建设探析
  4. 阿里架构师首次畅谈余额宝背后的故事
  5. (转)智能投顾面临的法律合规问题及国际监管经验
  6. julia的几种画图方法
  7. HPC+AI融合发展的挑战和应对方法探讨
  8. Gartner 2020年十大战略科技发展趋势:边缘赋能、区块链、超自动化、人工智能安全等...
  9. 【汇率预测】基于matlab模拟退火算法优化BP神经网络汇率预测【含Matlab源码 689期】
  10. 【细胞分割】基于matlab中值滤波+分水岭法细胞计数【含Matlab源码 640期】