什么是web componets, 它的出现是为了什么?
web components旨在提供一套制作可重用的封装性好的自定义元素的标准。
它包括四部分:
customElements -- 这是一个基于CustomeElementRegistry类生成的对象,用于注册自定义元素,如customElements.define('my-popup', MyPop), 并返回已注册的自定义元素的信息。经过注册的元素就可以直接在html页面上像普通元素那样使用了,如<my-popup/>
shadow DOM -- 影子DOM
HTML template -- HTML模板
HTML import -- HTML导入
customElements.define用于注册自定义元素,那什么是自定义元素呢?
自定义元素即为一个class,在这个class里添加各种内置的元素并实现一些逻辑。如果想在页面上使用这个自定义元素,需要用CustomElementRegistry
的define来注册一下。
自定义元素有两种
1 autonomous custom elements
extends HTMLElement, 可以通过<popup-info>或doducment.createElement("popup-info")引入到页面
注册: customElements.define("popup-info", PopupInfo);
2 customized built-in elements
继承自基础的html elements,比如div /p/ span等,需要添加is属性来引入到页面,<p is="word-count">或 document.createElement("p", {is:"word-count"})
注册: customElements.define('expanding-list', ExpandingList, {extends:"ul"});
很明显的看出来,customize built-in elements注册时,需要提供第三个参数,来表明是继承自谁
自定义元素的生命用期:
-
connectedCallback
:当 custom element首次被插入文档DOM时,被调用。 -
disconnectedCallback
:当 custom element从文档DOM中删除时,被调用。 -
adoptedCallback
:当 custom element被移动到新的文档时,被调用。 -
attributeChangedCallback
: 当 custom element增加、删除、修改自身属性时,被调用。这个回调需要自定义组件提示 static get observedAttributes(){return ['属性名','属性名',...];}。如果在组件还没 append到某元素上,此时setAttribute也会触发该事件。
这些都可以在自定义元素的class里直接引入来针对不同的阶段进行相应的业务处理。
Shadow DOM
它是document node的一种。对保证组件的独立,使其行为、样式、事件等不受外部的影响起关键作用。它给自定义组件里的元素提供了一个隐蔽的分离出来的DOM.
与Shadow DOM相关的几个术语:
- shadow host 是一个普通的dom元素,用来安放shdow dom
- shadow tree dom树
- shadow boundary shadow dom的边界,表示shadow dom结束,regular dom开始
- shadow root shadow tree的根
shadow DOM的基本用法
this.attachShadow({mode:'open'}),将shadow root加到自定义元素上。mode有两个值:open和closed。open的话,在外边也可以访问到组件的shadowRoot,closed的正好相反.
let myShadowDom = myCustomElem.shadowRoot;
mode为open时myShadowDom可以取到值,并能对里边的元素做操作。mode为close时myShadowDom为null;
function updateStyle(elem) {
const shadow = elem.shadowRoot; // 访问自定义组件的shadow root
shadow.querySelector('style').textContent = `
div {
width: ${elem.getAttribute('l')}px;
height: ${elem.getAttribute('l')}px;
background-color: ${elem.getAttribute('c')};
}
`; // shadow root有跟document类似的方法如getElementById,querySelector等
}
slot和template
在shadow dom中引入slot来增加灵活性。搭配使用template效果更佳。
slot让用户可给向自定义组件里添加自己的标签元素。它通过name属性来指定一个slot,所以组件内的slot的name要唯一。
<template>标签里的代码片断(DocumentFragment)不会被rend到页面上,只能通过javascript的Node.cloneNode克隆出新的DocumentFragment然后后再appendChild或是insertBefore来加来到dom树上。
template里的documentFragment通过HTMLTemplateElement.content来取得。
<template id="element-details-template">
<style>
details {font-family: "Open Sans Light",Helvetica,Arial}
.name {font-weight: bold; color: #217ac0; font-size: 120%}
h4 { margin: 10px 0 -8px 0; }
h4 span { background: #217ac0; padding: 2px 6px 2px 6px }
h4 span { border: 1px solid #cee9f9; border-radius: 4px }
h4 span { color: white }
.attributes { margin-left: 22px; font-size: 90% }
.attributes p { margin-left: 16px; font-style: italic }
</style>
<details>
<summary>
<span>
<code class="name"><<slot name="element-name">NEED NAME</slot>></code> <!--slot->
<i class="desc"><slot name="description">NEED DESCRIPTION</slot></i> <!--slot->
</span>
</summary>
<div class="attributes">
<h4><span>Attributes</span></h4>
<slot name="attributes"><p>None</p></slot> <!--slot ->
</div>
</details>
<hr>
</template>
customElements.define('element-details',
class extends HTMLElement {
constructor() {
super(); // constructor里先写上super,this才能被赋值
var template = document
.getElementById('element-details-template')
.content;// template可以通过dom的方法来取到,它的content属性返回的就是内部的DocumentFragment
const shadowRoot = this.attachShadow({mode: 'open'}) // 自定义组件首先要创建shadow,通过appendChild来往shadow里添加标签元素
.appendChild(template.cloneNode(true));
}
})
<element-details>
<span slot="element-name">slot</span> <!--通过给标签添加slot="slotName"来将这个标签填充到自定义标签里->
<span slot="description">A placeholder inside a web
component that users can fill with their own markup,
with the effect of composing different DOM trees
together.</span>
<dl slot="attributes"> <!--如果不给名称为attribute的slot写标签的话,会用自定义组件里的该slot内的标签->
<dt>name</dt>
<dd>The name of the slot.</dd>
</dl>
</element-details>
还有一个与此相关的css伪类:define :host :host-context,方法,可以用到时再学习
总结
实现web componets的步骤与方法如下:
https://developer.mozilla.org/zh-CN/docs/Web/Web_Components
学习web components的更多相关文章
-
web Components 学习之路
就目前而言,纯粹的Web Components在兼容性方面还有着较为长远的路,这里做个记录总结,以纪念自己最近关于Web Components的学习道路. 参考教材 JavaScript 标准参考教程 ...
-
【shadow dom入UI】web components思想如何应用于实际项目
回顾 经过昨天的优化处理([前端优化之拆分CSS]前端三剑客的分分合合),我们在UI一块做了几个关键动作: ① CSS入UI ② CSS作为组件的一个节点而存在,并且会被“格式化”,即选择器带id前缀 ...
-
Web Components之Custom Elements
什么是Web Component? Web Components 包含了多种不同的技术.你可以把Web Components当做是用一系列的Web技术创建的.可重用的用户界面组件的统称.Web Com ...
-
【转】Facebook React 和 Web Components(Polymer)对比优势和劣势
原文转自:http://segmentfault.com/blog/nightire/1190000000753400 译者前言 这是一篇来自 * 的问答,提问的人认为 Rea ...
-
Facebook React 和 Web Components(Polymer)对比优势和劣势
目录结构 译者前言 Native vs. Compiled 原生语言对决预编译语言 Internal vs. External DSLs 内部与外部 DSLs 的对决 Types of DSLs - ...
-
Fiori Fundamentals和SAP UI5 Web Components
这周有位同事邀请我给团队讲一讲SAP技术的演进历史,所以我准备了下面几个主题来介绍. 其中SAP的技术回顾和演进,我的思路就是从前后台两方面分别介绍. 我画了一张非常简单的图: 去年5月我写过一篇文章 ...
-
Web Components 入门实例教程
转自阮一峰http://www.ruanyifeng.com/blog/2019/08/web_components.html 组件是前端的发展方向,现在流行的 React 和 Vue 都是组件框架. ...
-
Web API之Web Components
本文参考<你的前端框架要被web组件替代了>. 于2011年面世的Web Components是一套功能组件,让开发者可以使用 HTML.CSS 和 JavaScript 创建可复用的组件 ...
-
Lightning Web Components 安装试用(一)
Lightning Web Components 简称(lwc) 是一个快速企业级的web 组件化解决方案,同时官方文档很全,我们可以完整的 学习lwc 项目结构 使用npx 官方提供了一个creat ...
随机推荐
-
Beaglebone Black&ndash;GPIO 开关 LED(三极管与继电器实验)
上一篇,用 GPIO 直接供电给 LED,用高低电平作开关,不靠谱.GPIO 是信号用的,不是当电源用的.而且,一个 GPIO 只能给可怜的 5mA 左右,取多了会烧(我没烧过不知道是不是真的会烧,但 ...
-
从客户端(MuliteTextBox2=";<;a href=";http://www....";)中检测到有潜在危险的 Request.Form 值
由于在.net中,Request时出现有HTML或Javascript等字符串时,系统会认为是危险性值.立马报出“从客户端 中检测到有潜在危险的Request.Form值”这样的错. 解决方案一: ...
-
call/apply的第一个参数如果为null。this指向window
call/apply是用来改变函数的作用域的,第一次参数为this,第二个参数为传输的值,例如 var a ="windowA"; var b = "windowB&qu ...
-
[Oracle]TRIGGER
题外话: Oracle 的使用. 以前客户方用的是SQL SERVER,一直在用SQL SERVER,感觉SQL SERVER的用户体验非常好. 不管是开发环境的界面布局到SQL 的写法上,感觉写起来 ...
-
websocket+前后端分离+https的nginx配置
后端服务路径: 172.168.0.2:8080 172.168.0.2:7080 前端目录(html + css + js): /root/apps/mzsg-web 1.修改 /etc/nginx ...
-
nodejs a和b文件相互引用
//取自于node中文网 http://nodejs.cn/api/modules.html 当循环调用 require() 时,一个模块可能在未完成执行时被返回. 例如以下情况: a.js: con ...
-
Linux安装git和maven的详细过程
一.使用yum安装git 当前安装环境是centos6.5 由于在CentOS6的yum源中已经有git的版本了,可以直接使用yum源进行安装 yum -y install git 由于centos6 ...
-
[NOI2009]变换序列
Description Input Output Sample Input 5 1 1 2 2 1 Sample Output 1 2 4 0 3 HINT 30%的数据中N≤50: 60%的数据中N ...
-
lua 语言基础
1.数据类型: string(字符串) ·运算符“+.-.*./”等操作字符串,lua会尝试讲字符串转换为数字后操作: ·字符串连接用“..”运算符 ·用“#”来计算字符串的长度(放在字符串前面) · ...
-
基于jQuery实现点击列表加载更多效果
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> < ...