百万个冷知识百万个冷知识

百万个冷知识
一起学习百万个冷知识

甚么是CSS?甚么是CSS操作方式?

shadow dom 是甚么?

简而言之,shadow dom意译不然是另一面dom,但我更愿把它认知为DOM中的DOM。因为他能为Web模块中的 DOM和 CSS提供更多了PCB,事实上是在应用程序图形文件格式的这时候会给选定的DOM内部结构填入撰写好的DOM原素,但填入的Shadow DOM 会与主文件格式的DOM维持分立,也是说Shadow DOM不存有于主DOM树下。

因此Shadow DOMPCB出的DOM原素是分立的,内部的实用性不能负面影响到内部,内部的实用性也不能负面影响内部。

如果这篇该文有协助到你,❤️高度关注+点赞❤️引导呵呵译者,该文社会公众号首秀,高度关注后端南玖第三时间以获取新一代该文~

思索

认知完它的基本概念,他们再来思索两个问题:

为甚么他们用的一些条码没错是两个空原素,自已能图形出各式各样繁杂的情景?

inputvideoaudiotextarea等...

可能许多老师都没人过为甚么那些条码跟他们常见的div条码不那样,它就单纯写个条码就能图形出相关联的式样与机能;

或是很多老师认知成这都是下层图形的事,他们无须重视。

是的,那些条码内部的文本的确都是下层图形的,但他们也不是看不出它内部的同时实现基本原理。

查阅html原生植物条码的Shadow DOM

在html中载入下列条码,接着到应用程序控制面板去查阅

许多人看见的是这样的,但这和他们写的没有任何人差别呀?喽,这就带你看一看他们的真实世界本来面目~

首先打开应用程序控制面板的设置选项

接着再找到Preference -> Elements,把show user anent shadow dom勾上

这这时候他们再来看呵呵此时的dom原素发生了甚么变化

他们会发现那些条码内部都大有乾坤,在那些条码下面都多了两个shadow root,在它里面才是那些条码的真实世界布局。

既然那些条码内部都有一些子原素布局,那么他们能不能通过JavaScript来访问到它呢?

const input = document.querySelector(input) console.log(input.firstChild) // null

很明显,这是不可以的!

因为它为web开发者设定了两个边界,界定了哪些是你可以访问的,哪些同时实现细节是访问不到的。然而,应用程序本身却可以随意跨越这个边界。设置这样两个边界之后,它就可以在你看不见的地方使用熟悉的web技术、同样的HTML原素去创建更多的机能,而不是像你那样要在页面上用div和span来堆。

shadow dom 内部结构

Shadow DOM允许将隐藏的 DOM 树附加到常规的 DOM 树中——它以shadow root节点为起始根节点,在这个根节点的下方,可以是任意原素,和普通的 DOM 原素那样。

是因为这个特点所以他们才能看见上面那些单个空条码就能图形出各式各样各样的繁杂情景。

上面这张图非常直观的表现了shadow dom的内部结构以及它与真实世界dom的关系。

shadow host

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

shadow bounday

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

shadow tree

Shadow DOM 内部的 DOM 树。

shadow root

Shadow tree 的根节点。

如何使用shadow dom?

创建两个shadow dom

他们可以使用attachShadow给选定原素挂载两个shadow dom,因此返回对shadow root的引用。

const shadowroot = root.attachShadow({mode: open}) const template = `
后端南玖
` shadowroot[xss_clean] = template

shadow dom mode

当调用Element.attachShadow()方法t时,必须通过传递两个对象作为参数来选定shadow DOM树的PCB模式,否则将会抛出两个TypeError。该对象必须具有mode属性,值为open或closed。

openshadow root 原素可以从 js 内部访问根节点,例如使用Element.shadowRoot:
element.shadowRoot; // 返回两个 ShadowRoot 对象
closed拒绝从 js 内部访问关闭的 shadow root 节点
element.shadowRoot; // 返回 null

应用程序通常见关闭的 shadow roo 来使某些原素的同时实现内部不可访问,而且不可从JavaScript更改。

对于一些不希望公开shadow root 的Web模块来说,封闭的shadow DOM看起来非常方便,然而在实践中绕过封闭的shadow DOM并不难。但完全隐藏shadow DOM所需的工作量也大大超过了它的价值。

哪些原素可以挂载shadow dom?

这里需要注意的是并非所有html原素都可以挂载shadow dom,只有下列那些原素可以充当shadow dom的 shadow host

articleasideblockquotebodydivfooterh1h2h3h4h5h6headermainnavpsectionspan任何人带有有效的名称且可分立存有的自定义原素

当他们尝试在其它原素挂在shadow dom时,应用程序则会抛出异常。

const input = document.querySelector(input) const inputRoot = input.attachShadow({mode: open})

shadow dom的特点

从前面的介绍,他们知道shadow dom是游离在 DOM 树之外的节点树,但它是基于普通 DOM 原素(非 document)创建的,因此创建后的 Shadow-dom 节点可以从界面上直观的看见。最重要的一点是Shadow-dom 具有良好的密封性。

式样

.wx_name { color:aqua; }
我是真实世界dom

它图形出是下面这样的 :

上面他们说了shadow dom是游离在 DOM 树之外的节点树,所以他们文件格式上的CSS就不能作用在他身上。

式样化host原素

host伪类选择器允许你从shadow root中的任何人地方访问shadow host

const shadowroot = root.attachShadow({mode: open}) const template = `
shadow dom - 后端南玖
:host { border: 1px solid ccc; color: pink; } ` shadowroot[xss_clean] = template

需要注意的是:host仅在shadow root中有效,因此在shadow root之外定义的式样规则比:host中定义的规则具有更高的特殊性。

式样钩子

shadow dom还有两个非常重要的两个特点是可以使用CSS自定义属性来创建式样占位符,并允许用户填充。

root { --bg: coral; --color: fff: }

通过CSS访问shadow

如果他们想要自定义一些原生植物条码的式样应该怎样做呢,很显然常规的CSS选择器并不能以获取到shadow dom内部原素。那他们就一点办法没有了吗?其实这里他们可以通过一些伪原素来同时实现,比如:

它默认长这样

那他们怎么去改变他的式样呢,比如给它换种背景色

直接给input写背景色能同时实现吗?

input{ background: ccc; }

很显然这是一种大聪明行为,那它就这两个原素,究竟怎样才能改变它的背景色呢,上面他们不是说了吗,它内部是有shadow dom的

input[type=range]::-webkit-slider-runnable-track { -webkit-appearance: none; background-color: chocolate; }

他们可以通过伪原素来访问到shadow的内部原素并改变其式样。

事件

在shadow DOM内触发的事件可以穿过shadow边界并冒泡到light DOM;但Event.target的值会自动更改,因此它看起来好像该事件源自其包含的shadow树而不是实际原素的host原素。

此更改称为事件重定向,其背后的原因是保留shadow DOMPCB。

当点击shadow dom中的任何人原素时,打印出的都是root,监听器无法看见调度该事件的真实世界原素。

自定义原素托管shadow DOM

模拟微信小程序条码

Custom Elements API 创建的自定义原素可以像其他原素那样托管shadow DOM。

后端南玖

上面这段代码是模拟微信小程序的条码同时实现,这里为甚么又跳到了小程序?因为微信小程序的同时实现基本原理跟这类似,他们知道小程序的图是在WebView里图形的,那搭建视图的方式自然就需要用到HTML语言。接着为了管控安全,肯定不可能让开发者直接使用html来进行开发,所以就自己同时实现了一套模块组织框架Exparser内置在小程序基础库中。这里的Exparser框架模型上与WebComponents的ShadowDOM高度相似,但不依赖应用程序的原生植物支持,也没有其他依赖库。

如何查阅小程序编译后的条码

许多人可能会有疑惑,他们在小程序中写的条码不是这样的呀,它都不带有wx前缀。是的,为了开发者使用方便,开发时是不需要带wx前缀的,在编译过程会自动识别比对转换成真实世界DOM。

他们可以打开微信开发者工具,调试微信开发者工具,接着在控制面板输入document.getElementsByTagName(webview)[0].showDevTools(true,null)接着它会打开另外两个控制面板,在这里就能看见类似他们上面同时实现的文本了

推荐阅读

性能优化之html、css、js三者的加载顺序Vue异步更新机制以及$nextTick基本原理超全面总结Vue面试知识点,助力金三银四【面试必备】后端常见的排序算法CSS性能优化的几个技巧后端常见的安全问题及防范措施为甚么大厂后端监控都在用GIF做埋点?后端人员不要只知道KFC,你应该了解 BFC、IFC、GFC 和 FFC原文首秀地址点这里,欢迎大家高度关注社会公众号「后端南玖」,如果你想进后端交流群一起学习,请点这里

我是南玖,他们下期见!!!

未经允许不得转载:百万个冷知识 » 甚么是CSS?甚么是CSS操作方式?
分享到: 更多 (0)

百万个冷知识 带给你想要内容

联系我们