2024年前端最新Web Components 是个什么样的东西,2024年最新阿里三面面经

最后

前15.PNG

前16.PNG

由于文档内容过多,为了避免影响到大家的阅读体验,在此只以截图展示部分内容

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

Web Components 现在提供多了一个这个:

HTMLLinkElement

原本的 link 标签在添加了 HTML Import 之后,多了一个只读的 import 属性,当出现下边两种情况时,这个属性为 null

  • 该 link 不是用来 import 一个 HTML 的。

  • 该 link 元素不在 document 中。

否则,这个属性会返回一个表示引入的 HTML 文件的文档对象,类似于 document。比如说,在上边的代码基础上,可以这样做:

const link = document.querySelector(‘link[rel=import]’)

const header = link.import;

const pulse = header.querySelector(‘div.logo’);

阻塞式

我们要知道的是,默认的 link 加载是阻塞式的,除非你给他添加一个 async 标识。

阻塞式从某种程度上讲是有必要的,当你 improt 的是一个完整的自定义组件并且需要在主 HTML 中用标签直接使用时,非阻塞的就会出现错误了,因为标签还没有被注册。

document

有一点值得留意的是,在 import 的 HTML 中,我们编写的 script 里边的 document 是指向 import 这个 HTML 的主 HTML 的 document。

如果我们要获取 import 的 HTML 的 document 的话,得这么来:

const d = document.currentScript.ownerDocument

这样设计是因为 import 进来的 HTML 需要用到主 HTML 的 document。例如我们上边提到的 registerElement

在一个被 import 的 HTML 文件中使用下边三个方法会抛出一个 InvalidStateError 异常:

  • document.open()

  • document.write()

  • document.close()

对于 HTML Import,标准文档中还有很大一部分内容是关于多个依赖加载的处理算法的,在这里就不详述了,有机会的话找时间再开篇谈,这些内容是需要浏览器去实现的。

HTML Templates


概述

这个东西很简单,用过 handlebars 的人都知道有这么一个东西:

其他模板引擎也有类似的东西,那么 HTML Templates 便是把这个东西官方标准化,提供了一个 template 标签来存放以后需要但是暂时不渲染的 HTML 代码。

以后可以这么写了:

接口和应用

template 元素有一个只读的属性 content,用于返回这个 template 里边的内容,返回的结果是一个 DocumentFragment

具体是如何使用的,直接参考官方给出的例子:

<!doctype html>

Homework

Smile!

使用 DocumentFragment 的 clone 方法以 template 里的代码为基础创建一个元素节点,然后你便可以操作这个元素节点,最后在需要的时候插入到 document 中特定位置便可以了。

Template 相关的东西不多,而且它现在已经是纳入生效的 标准文档 中了。

我们接下来看看重磅的 Shadow DOM。

Shadow DOM


概述

Shadow DOM 好像提出好久了,最本质的需求是需要一个隔离组件代码作用域的东西,例如我组件代码的 CSS 不能影响其他组件之类的,而 iframe 又太重并且可能有各种奇怪问题。

可以这么说,Shadow DOM 旨在提供一种更好地组织页面元素的方式,来为日趋复杂的页面应用提供强大支持,避免代码间的相互影响。

看下在 chrome 它会是咋样的:

我们可以通过 createShadowRoot() 来给一个元素节点创建 Shadow Root,这些元素类型必须是下边列表的其中一个,否则会抛出 NotSupportedError 异常。

  • 自定义的元素

  • article

  • aside

  • blockquote

  • body

  • div

  • header, footer

  • h1, h2, h3, h4, h5, h6

  • nav

  • p

  • section

  • span

createShadowRoot() 是现在 chrome 实现的 API,来自文档:https://www.w3.org/TR/2014/WD…。最新的文档 API 已经调整为 attachShadow()

返回的 Shadow Root 对象从 DocumentFragment 继承而来,所以可以使用相关的一些方法,例如shadowRoot.getElementById('id') 来获取 Shadow DOM 里边的元素。

简单的使用如下:

const div = document.getElementById(‘id’)

const shadowRoot = div.createShadowRoot()

const span = document.createElement(‘span’)

span.textContent = ‘hello world’

shadowRoot.appendChild(span)

在这里,我把这个 div 成为是这个 Shadow DOM 的 宿主元素,下边的内容会延续使用这个称呼。

Shadow DOM 本身就为了代码隔离而生,所以在 document 上使用 query 时,是没法获取到 Shadow DOM 里边的元素的,需要在 Shadow Root 上做 query 才行。

在这里附上一个文档,里边有详细的关于新的标准和现在 blink 引擎实现的 Shadow DOM 的区别,官方上称之为 v0 和 v1:Shadow DOM v1 in Blink

API

Shadow Root 除了从 DocumentFragment 继承而来的属性和方法外,还多了另外两个属性:

  • host 只读属性,用来获取这个 Shadow Root 所属的元素

  • innerHTML 用来获取或者设置里边的 HTML 字符串,和我们常用的 element.innerHTML 是一样的

另外,在最新的标准文档中,元素除了上边提到的 attachShadow 方法之外,还多了三个属性:

  • assignedSlot 只读,这个元素如果被分配到了某个 Shadow DOM 里边的 slot,那么会返回这个对应的 slot 元素

  • slot 元素的 slot 属性,用来指定 slot 的名称

  • shadowRoot 只读,元素下面对应的 Shadow Root 对象

slot 是什么?接着看下边的内容,看完下一节的最后一部分就会明白上述内容和 slot 相关的两个 API 有什么作用。

slot

slot 提供了在使用自定义标签的时候可以传递子模板给到内部使用的能力,可以简单看下 Vue 的一个例子。

我们先来看下现在 chrome 可以跑的 v0 版本,这一个版本是提供了一个 content 标签,代表了一个占位符,并且有一个 select 属性用来指定使用哪些子元素。

自定义的元素里边的子元素代码是这样的:

hello

test

那么展现的结果会和下边的代码是一样的:

test

这里只是说展现结果,实际上,input-toggle 里边应该是创建了一个 Shadow DOM,然后 content 标签引用了目标的 span 内容,在 chrome 看是这样的:

然后,是最新标准中的 slot 使用方式,直接上例子代码:

在自定义的元素标签是这么使用 slot 的:

test

通过 slot="text" 的属性来让元素内部的 slot 占位符可以引用到这个元素,多个元素使用这个属性也是可以的。这样子我们便拥有了使用标签是从外部传 template 给到自定义元素的内部去使用,而且具备指定放在那里的能力。

CSS 相关

因为有 Shadow DOM 的存在,所以在 CSS 上又添加了很多相关的东西,其中一部分还是属于讨论中的草案,命名之类的可能会有变更,下边提及的内容主要来自文档:Shadow DOM in CSS scoping 1,很多部分在 chrome 是已经实现的了,有兴趣可以写 demo 试试。

因为 Shadow DOM 很大程度上是为了隔离样式作用域而诞生的,主文档中的样式规则不对 Shadow DOM 里的子文档生效,子文档中的样式规则也不影响外部文档。

但不可避免的,在某些场景下,我们需要外部可以控制 Shadow DOM 中样式,如提供一个组件给你,有时候你会希望可以自定义它内部的一些样式,同时,Shadow DOM 中的代码有时候可能需要能够控制其所属元素的样式,甚至,组件内部可以定义上边提到的通过 slot 传递进来的 HTML 的样式。所以呢,是的,CSS 选择器中添加了几个伪类,我们一一来看下它们有什么作用。

在阅读下边描述的时候,请留意一下选择器的代码是在什么位置的,Shadow DOM 内部还是外部。

:host 用于在 Shadow DOM 内部选择到其宿主元素,当它不是在 Shadow DOM 中使用时,便匹配不到任意元素。

在 Shadow DOM 中的 * 选择器是无法选择到其宿主元素的。

:host( <selector> ) 括号中是一个选择器,这个可以理解为是一个用于兼容在主文档和 Shadow DOM 中使用的方法,当这个选择器在 Shadow DOM 中时,会匹配到括号中选择器对应的宿主元素,如果不是,则匹配括号中选择器能够匹配到的元素。

文档中提供了一个例子:

<“shadow tree”>

...

</>

在这个 shadow tree 内部的样式代码中,会有这样的结果:

  • :host 匹配 <x-foo> 元素

  • x-foo 匹配不到元素

  • .foo 只匹配到 <div> 元素

  • .foo:host 匹配不到元素

  • :host(.foo) 匹配 <x-foo> 元素

:host-context( <selector> ),用于在 Shadow DOM 中来检测宿主元素的父级元素,如果宿主元素或者其祖先元素能够被括号中的选择器匹配到的话,那么这个伪类选择器便匹配到这个 Shadow DOM 的宿主元素。个人理解是用于在宿主元素外部元素满足一定的条件时添加样式。

::shadow 这个伪类用于在 Shadow DOM 外部匹配其内部的元素,而 /deep/ 这个标识也有同样的作用,我们来看一个例子:

<“shadow tree”>

</>

对于上述这一段代码的 HTML 结构,在 Shadow DOM 外部的样式代码中,会是这样的:

  • x-foo::shadow > span 可以匹配到 #top 元素

  • #top 匹配不到元素

  • x-foo /deep/ span 可以匹配到 #not-top 和 #top 元素

/deep/ 这个标识的作用和我们的 > 选择器有点类似,只不过它是匹配其对应的 Shadow DOM 内部的,这个标识可能还会变化,例如改成 >> 或者 >>> 之类的,个人感觉, >> 会更舒服。

最后一个,用于在 Shadow DOM 内部调整 slot 的样式,在我查阅的这个文档中,暂时是以 chrome 实现的为准,使用 ::content 伪类,不排除有更新为 ::slot 的可能性。我们看一个例子来了解一下,就算名称调整了也是差不多的用法:

...
...
...

<“shadow tree”>

...
...

</“shadow tree”>

在 Shadow DOM 内部的样式代码中,::content div 可以匹配到 #one#three 和 #four,留意一下 #two 为什么没被匹配到,因为它没有被 content 元素选中,即不会进行引用。如果更换成 slot 的 name 引用的方式亦是同理。

层叠规则,按照这个文档的说法,对于两个优先级别一样的 CSS 声明,没有带 !important 的,在 Shadow DOM 外部声明的优先级高于在 Shadow DOM 内部的,而带有 !important 的,则相反。个人认为,这是提供给外部一定的控制能力,同时让内部可以限制一定的影响范围。

继承方面相对简单,在 Shadow DOM 内部的顶级元素样式从宿主元素继承而来。

至此,Web Components 四个部分介绍结束了,其中有一些细节,浏览器实现细节,还有使用上的部分细节,是没有提及的,因为详细记录的话,还会有很多东西,内容很多。当使用过程中有疑问时可以再次查阅标准文档,有机会的话会再完善这个文章。下一部分会把这四个内容组合起来,整体看下 Web Components 是怎么使用的。

Web Components


Web Components 总的来说是提供一整套完善的封装机制来把 Web 组件化这个东西标准化,每个框架实现的组件都统一标准地进行输入输出,这样可以更好推动组件的复用。结合上边各个部分的内容,我们整合一起来看下应该怎么使用这个标准来实现我们的组件:

这是一个简单的组件的例子,用于定义一个 test-header,并且给传递进来的子元素 li 添加了一些组件内部的样式,同时给组件绑定了一个点击事件,来打印点击目标的文本内容。

看下如何在一个 HTML 文件中引入并且使用一个组件:

最后

推荐一些系统学习的途径和方法。

路线图

每个Web开发人员必备,很权威很齐全的Web开发文档。作为学习辞典使用,可以查询到每个概念、方法、属性的详细解释,注意使用英文关键字搜索。里面的一些 HTML,CSS,HTTP 技术教程也相当不错。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

HTML 和 CSS:

html5知识

css基础知识

rototype: element })

})()

这是一个简单的组件的例子,用于定义一个 test-header,并且给传递进来的子元素 li 添加了一些组件内部的样式,同时给组件绑定了一个点击事件,来打印点击目标的文本内容。

看下如何在一个 HTML 文件中引入并且使用一个组件:

最后

推荐一些系统学习的途径和方法。

路线图

每个Web开发人员必备,很权威很齐全的Web开发文档。作为学习辞典使用,可以查询到每个概念、方法、属性的详细解释,注意使用英文关键字搜索。里面的一些 HTML,CSS,HTTP 技术教程也相当不错。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

HTML 和 CSS:

html5知识

css基础知识

  • 13
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值