Web Components的前世今生
点击关注公众号,”技术干货”及时达!引言发展历史Web Components 技术的发展历程可以分为以下几个阶段:
2011 年,Google 开始开发 Polymer 项目,旨在创建一种基于 Web 标准的新型 Web 应用开发框架。2013 年,W3C 开始制定 Web Components 标准,包括 Custom Elements、HTML Templates 和 Shadow DOM 等技术。2015 年,Web Components 1.0 草案发布。2017 年,Web Components 1.0 正式标准发布。2018 年,Chrome 63 正式支持 Web Components 技术。2019 年,Web Components 技术开始逐渐被更多的前端开发人员使用,成为前端开发的基础设施之一谁在使用1. youtubeimage.png2. githubimage.png3.quark-design(哈啰)image.png4.Vue也支持web Componentsimage.png目标了解web Components是什么。本文不是全面教程,只是一个简单演示,如果需要全面学习的话可以点我 进行全面学习
Web Components的基本概念Web Component 是一套不同的技术,允许你创建可重用的定制元素(它们的功能封装在你的代码之外)并且在你的 web 应用中使用它们。
如图, Web Components主要包括了下面的三个技术
image.pngCustom Elements概念由 Web 开发人员定义行为的 HTML 元素,扩展了浏览器中可用的元素集
实现方式有两种自定义内置元素 继承自标准的 HTML 元素,例如HTMLParagraphElement独立自定义元素继承自 HTML 元素基类HTMLElement例子如果你有vue的基础的话,vue的语法中有一个动态组件有一个attribute 「is」,代表的是哪个组件,这个自定义内置元素和vue的语法很像
可以先看下方的自定义元素的例子,我们对下面的代码做个解释
html中 p 标签的「is」 后有一个word-count 代表的就是我们使用了word-count的自定义元素script脚本中定义了一个wordCount类继承自HTMLParagraphElement在这个类中定义了一单词统计的功能最后注册了自定义元素(通过customElements)!DOCTYPEhtml
htmllang="en"
head
metacharset="UTF-8"/
metaname="viewport"content="width=device-width,initial-scale=1.0"/
titleDocument/title
/head
body
div
articlecontenteditable=""
pmynameisadu/p
pis="word-count"/p
/article
/div
script
classWordCountextendsHTMLParagraphElement{
constructor(){
super();
//得到父亲节点
varwcParent=this.parentNode;
//创建影子节点
varshadow=this.attachShadow({mode:"open"
varcount="Words:"+countWords(wcParent);
//创建一个span节点
vartext=document.createElement("span");
text.textContent=count;
//将创建的节点添加到影子节点
shadow.appendChild(text);
//200ms更新字数统计
setInterval(function(){
varcount="Words:"+countWords(wcParent);
text.textContent=count;
},200);
//定义统计字数的方法
functioncountWords(node){
vartext=node.innerText||node.textContent;
returntext.split(/\s+/g).length;
}
}
}
customElements.define("word-count",WordCount,{extends:"p"
/script
/body
/html
上方的代码的预览效果
5d2d72e6-fb23-4d87-b5d6-6bed11801db7.gif生命周期当然自定义元素也有有生命周期的,我们对上方的代码进行扩展
「改动点为」
添加了个「删除的button」在constuctor下方的节点添加了两个事件「connectedCallback」(当自定义元素第一次被连接到文档 DOM 时被调用。)、「disconnectedCallback」(当自定义元素与文档 DOM 断开连接时被调用)下方为demo的预览gif
当然Custom element 还有更多的生命周期(adoptedCallback、attributeChangedCallback),我们就不介绍了。
Shadow DOM概念对标签和样式的一层 DOM 包装,你将一个 DOM 树附加到一个元素上,并且使该树的内部对于在页面中运行的 JavaScript 和 CSS 是隐藏的。
设置浏览器这个概念也许有点模糊,我们先不写代码,先打开你的浏览器设置,我们来看个设置
shadow Dom 也许你不注意,平常使用的input,video等其实都是由shadow dom开发的
「首先打开浏览器控制台的设置选项」
「然后再找到Preference - Elements,把show user anent shadow dom勾上」
)
浏览器的video,为什么我们只是引入了,就自动生成了暂停、音量、进度条,其实这些都是shadow Dom的的功劳
例子关键代码解释
`attachShadow()`[1]来创建影子 DOMmode设置为"open"时,页面中的 JavaScript 可以通过影子宿主的`shadowRoot`[2]属性访问影子 DOM 的内部。很简单的代码,我们就创建了一个shadow dom
!DOCTYPEhtml
htmllang="en"
head
metacharset="UTF-8"/
metaname="viewport"content="width=device-width,initial-scale=1.0"/
titleDocument/title
/head
body
divid="host"/div
span我是普通dom/span
script
consthost=document.querySelector("#host");
constshadow=host.attachShadow({mode:"open"
constspan =document.createElement("span");
span.textContent="我是shadowdom";
shadow.appendChild(span);
/script
/body
/html
运行效果如下
对JS上来说基本上是隐藏的通过querySelector是获取不到元素的,{ mode: "open" }传入attachShadow()。当mode设置为"open"时,页面中的 JavaScript 可以通过影子宿主的`shadowRoot`[3]属性访问影子 DOM 的内部,当mode是closed,此时shadowRoot返回null
!DOCTYPEhtml
htmllang="en"
head
metacharset="UTF-8"/
metaname="viewport"content="width=device-width,initial-scale=1.0"/
titleDocument/title
/head
body
divid="host"/div
span我是普通dom/span
buttononClick="onLogSpanLength()"打印Span的长度/button
script
consthost=document.querySelector("#host");
constshadow=host.attachShadow({mode:"open"
constspan =document.createElement("span");
span.textContent="我是shadowdom";
shadow.appendChild(span);
functiononLogSpanLength(){
console.log(document.querySelectorAll("span").length);
console.log(document.querySelector("#host").shadowRoot.querySelectorAll("span").length)
}
/script
/body
/html
运行效果如下
image.pngCSS封闭性保持上方的代码不变,我们添加一个css的样式,
style
span{
color:blue;
border:1pxsolidblack;
}
/style
运行效果
image.png「shadow dom 的特点」
从前面的介绍,我们知道shadow dom是游离在 DOM 树之外的节点树,但是它是基于普通 DOM 元素(非 document)创建的,并且创建后的 Shadow-dom 节点可以从界面上直观的看到。「最重要的一点是Shadow-dom 具有良好的密封性。」
Template和Slottemplate概念template 顾名思义是模板,他有以下的特点HTML「内容模板」(template)元素是一种用于保存客户端内容机制,该内容在加载页面时不会呈现,但随后可以在运行时使用 JavaScript 实例化。
image.png上面的代码不会展示在你的页面中,直到你用 JavaScript 获取它的引用,然后添加到 DOM 中,如下面的代码:
image.pngslot熟悉 Vue 的同学应该都知道”插槽(slot)“的概念,通过使用插槽可以让页面内容的组织更加灵活。
的确,vue的设计灵感也来源此,下方的为官方的一个截图
image.png例子!DOCTYPE html
html lang="en"
head
meta charset="UTF-8" /
meta name="viewport" content="width=device-width, initial-scale=1.0" /
titleDocument/title
/head
body
!-- 定义一个模板 --
template id="templateId"
slot name="element-name"插槽的默认值/slot
/template
element-test/element-test
element-test
span slot="element-name"测试值/span
/element-test
script
customElements.define(
"element-test",
class extends HTMLElement {
constructor() {
super();
// 获取模板的内容
const template = document.getElementById(
"templateId"
).content;
// 创建一个shadow节点
const shadowRoot = this.attachShadow({ mode: "open" }).appendChild(
//将模板的拷贝到阴影的根结点上
template.cloneNode(true)
);
}
}
);
/script
/body
/html
效果如下图
image.png调试使用方式基本同vuedevtool相同 下载地址 下方的为github的截图
Inspector的Tab我们可以看到Proprrties、attriubutes、methods
Source的Tabimage.png在实际开发中的应用图片添加header当公司要求所有的请求包含图片添加 token图片添加自定义的header
方便调试样式假如设计师设计了placeholder为不同颜色,当我们不开启浏览器的默认样式的时候,看不到placeholder的内容,开启后,可以方便的看到内容,并且进行修改。
下方的截图为element ui的input的placeholder样式
image.png更好的理解不同的框架的配置比如我们公司使用的是qiankun
下方的为qiankun的截图,当你理解了shadowDom,你就可以更快的知道这个配置项的作用
image.png点击关注公众号,”技术干货”及时达!
阅读原文
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。 项目经理在线