影子节点 shadowDOM

shadow DOM是什么


上面这是最简单的视屏标签,里面有默认的音量等按键。在源代码中根本没有一点痕迹。那这些节点是从哪里来的?
  这就是shadow DOM,视屏的控件在浏览器中真实面目如下:


影子节点 shadowDOM_第1张图片
shadow DOM浏览器中体现

发现#shadow-root是灰色的,这是浏览器为了表明在shadow DOM中,代表页面其他的部分的内容不会对内部产生影响(可用特定方式穿透,后文会说到)

内容具体指css选择器和javascript代码

简而言之,Shadow DOM 是一个 HTML 的新规范,其允许开发者封装HTML组件(类似vue组件,将html,css,js独立部分提取)。

为什么要使用shadow DOM

Bootstrap的名字你一定不陌生,代码一般如下:


非常的简单好用,但是这些东西你并没有深入了解,往往结构变复杂之后,都是一堆模板,修改是一个很难的问题,牵一发而动全身。
  这种情况下shadow DOM的优势十分巨大,你可以这么写模板

// 我是一个简洁的模板

  
    ![](...)
  
  

Media heading

当然想实现这么写还需要一些js,css配合才行

如何使用

先运行一个例子

Hello, world!

运行结果

  首先我们指定一个 宿主节点shadow host)然后创建影子根( shadow root)为它添加一个文本节点,结果宿主中的内容未被渲染。

如何渲染宿主节点中的内容

只渲染影子根中的内容基本没有实用的地方,但能自由的渲染宿主节点中的内容的话就可以让页面展现更灵活。我们需要content标签

胖丁

影子节点 shadowDOM_第2张图片

   标签创建了一个**插入点 **将 .pokemon里面的文本投影出来,多个内容匹配时可以实用 select属性指定

大慈大悲,由诸葛亮进化而来。

观音姐姐兽


  可以使用 select属性类似选择器的形式渲染宿主节点中匹配元素的投影。这种形式不但可以改变DOM流的顺序也可以让布局变得灵活。
  在模板的最后 是一种贪心匹配,把宿主节点中所有未被匹配的内容全部投影。需要注意的是把贪心匹配放在最前面会把所有的节点投影并且之后的select不会再获取到被其投影的内容。
  以下都是等效的:

样式渲染与封装

先看一个简单的例子



影子节点 shadowDOM_第3张图片

  在影子节点中存在边界使 shadow DOM样式和正常DOM流中的样式不相互干扰。这是一种 作用域化的体现,不用再担心样式的相互冲突。

(:host)选择器

:host是伪类选择器选择宿主节点,我们可以扩展一下上面的例子


我的文本


  这个例子有几个点:

  • p标签字体大小是12px = 影子样式的优先级不如页面样式
  • :host选择器中可以使用任意合法选择器,*应用于所有
  • 通过挂载不同宿主渲染出不同的内容,可以实现主题化
      上面的主题化并不完全,只根据挂载元素进行选择也就是说.parent > .child,但是我们还能通过:host-context实现.parent < .child如下

serious-widget

playful-widget

影子节点 shadowDOM_第4张图片

上面的效果就非常不错了,可以进行动态组件构建

ps: 伪类,伪元素选择器也可以直接使用,效果和正常节点中一致

(::content)选择器

在使用 shadow DOM 的时候应该确保内容和表现的分离,也就是说文本应该来自页面而不是埋在 shadow DOM 的模板里。所以我们需要在模板中对分布式节点进行渲染。

打破作用域(::shadow)

我们可以在挂载节点中使用::shadow,比如






不过缺点是只能穿透一层,但我们还有一个神器!

多层穿透(/deep/)


影子节点 shadowDOM_第5张图片

javascript的区别

  1. 数据并没有块级化,仍挂载在window
  • 事件重定向(原来绑定在 shadow DOM 节点中的事件被重定向了,所以他们看起来像绑定在宿主节点上一样)


可以看到在影子节点的事件被宿主节点代理。

事件阻塞

在监听以下事件时会被阻塞在影子节点的根:

  • aborterror
  • select
  • change
  • load
  • reset
  • reset
  • resize
  • scroll
  • selectstar


事件影子节点的根上被阻止,无法冒泡到ducoment,所以无法监听。

分布节点

分布节点指之前通过标签将宿主节点的内容投影,分布节点不会发生上面的阻塞情况,因为这个只是一个投影实际的内容还是挂载在宿主节点上。

你可能感兴趣的:(影子节点 shadowDOM)