使用shadow dom封装web组件
什么是shadow dom?
首先我们先来看看它长什么样子。在HTML5中,我们只用写如下简单的两行代码,就可以通过 <video> 标签来创建一个浏览器自带的视频播放器控件。
<video controls="">
<source src="https://mdn.mozillademos.org/files/2587/AudioTest%20(1).ogg" type="audio/ogg">
</video>
而在各个浏览器中,它都有各不相同的外观展现,例如chrome中它长下面这样:
但为什么我们在dom中无法看到他们内部的结构?噢,实际上浏览器通过某种技术把它们隐藏起来而已,但我们可以通过 DevTools 设置中勾选Show user agent shadow DOM来看到这些结构。勾选后我们发现在 <video> 标签下多了 #shadow-root(user-agent) 这个东西,它包含了 video 控件的内部dom结构,这就是所谓的shadow dom了。
并且shadow dom为我们提供了简单有效的样式隔离。如果你尝试通过 input[type="button"] { display:none; } 之类的样式来影响控件外观,你会发现是无效的。这样如果我们通过 shadow dom 来隐藏控件的内部实现,就不用担心对样式表进行修改时对控件造成影响了。
下面我们来看看如何通过shadow dom来封装控件。
使用Shadow Dom封装控件
首先我们先看看w3c对shadow dom的描述:
A shadow host is an element that hosts one or more node trees.
A shadow tree is a node tree hosted by a shadow host.
A shadow root is the root node of a shadow tree.
这三句话告诉我们:
- - shadow dom 由一颗或多颗 shadow tree 组成,并且需要一个普通的dom元素作为它的容器
- - shadow tree 是一颗节点树
- - shadow root 是shadow tree的根节点
下面,我们直接通过一个例子来演示如何使用shadow dom来封装web组件:
DOM:
// 模板
<template id="wgTemplate">
<style>
color: #fff;
background: #006dcc;
</style>
<button type="button" class="btn">button widget</button>
</template> // shadow dom 容器
<div id="my-widget"></div>
JS:
// 创建shadow dom
<script type='text/javascript'>
var host = document.querySelector("#my-widget")
var tp = document.querySelector("#wgTemplate")
var clone = document.importNode(tp.content, true)
host.createShadowRoot().appendChild(clone)
</script>
- 第一步,我们需要一个shadow dom的容器 <div id="my-widget"></div>
- 随后通过 document.importNode() 获取到控件的模板并克隆
- 接着使用 createShadowRoot() 要创建一个shadow root作为shadow tree的根节点
- 最后将将模板内容 clone 作为shadow tree插入到shadow root中
打开页面,我们可以看到如下结构,这就是一个利用shadow隐藏控件内部实现最简单的例子了。
接着我们还可以结合上一篇文章《web component之custom element》的创建自定义元素的方法来封装自定义控件:
dom:
// 模板
<template id="wgTemplate">
<style>
.btn {
color: #fff;
background: #006dcc;
}
</style>
<button type="button" class="btn">custom button widget</button>
</template>
js:
// 创建自定义控件
<script type='text/javascript'>
var proto = Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
var tp = document.querySelector('#wgTemplate')
var clone = document.importNode(tp.content, true)
this.createShadowRoot().appendChild(clone)
}
}
}) var MyButtom = document.registerElement('my-buttom', {prototype: proto}) document.body.appendChild(new MyButtom())
</script>
使用shadow dom封装web组件的更多相关文章
- 【shadow dom入UI】web components思想如何应用于实际项目
回顾 经过昨天的优化处理([前端优化之拆分CSS]前端三剑客的分分合合),我们在UI一块做了几个关键动作: ① CSS入UI ② CSS作为组件的一个节点而存在,并且会被“格式化”,即选择器带id前缀 ...
- atitit. web组件化原理与设计
atitit. web组件化原理与设计 1. Web Components提供了一种组件化的推荐方式,具体来说,就是:1 2. 组件化的本质目的并不一定是要为了可复用,而是提升可维护性. 不具有复用 ...
- atitit.atiHtmlUi web组件化方案与规范v1
atitit.atiHtmlUi web组件化方案与规范v1 1. 如何在现有html 标签基础上定义自己的组件1 2. 组件的构成与定义1 3. 组件的加载1 4. 组件css的加载2 5. 操作组 ...
- 究竟什么是Shadow DOM?
shadow dom 是什么? 顾名思义,shadow dom直译的话就是影子dom,但我更愿把它理解为DOM中的DOM.因为他能够为Web组件中的 DOM和 CSS提供了封装,实际上是在浏览器渲染文 ...
- 从原生web组件到框架组件源码(三)
快乐的时光都是这么短暂,转眼间,web原生组件的知识点已经学完了,这个虽然暂时不一定有用,但是随着时间的积累,一步一个脚印的积累,你会有相应的收获,希望能变得更强,比如两年前我也会想有现成的东西不用, ...
- JavaScript 是如何工作:Shadow DOM 的内部结构 + 如何编写独立的组件!
这是专门探索 JavaScript 及其所构建的组件的系列文章的第 17 篇. 如果你错过了前面的章节,可以在这里找到它们: JavaScript 是如何工作的:引擎,运行时和调用堆栈的概述! Jav ...
- 【Web技术】401- 在 React 中使用 Shadow DOM
本文作者:houfeng 1. Shadow DOM 是什么 Shadow DOM 是什么?我们先来打开 Chrome 的 DevTool,并在 'Settings -> Preferences ...
- 【Web技术】400- 浅谈Shadow DOM
编者按:本文作者:刘观宇,360 奇舞团高级前端工程师.技术经理,W3C CSS 工作组成员. 为什么会有Shadow DOM 你在实际的开发中很可能遇到过这样的需求:实现一个可以拖拽的滑块,以实现范 ...
- JS21. 使用原生JS封装一个公共的Alert插件(HTML5: Shadow Dom)
效果预览 Shadow DOM Web components 的一个重要属性是封装--可以将标记结构.样式和行为隐藏起来,并与页面上的其他代码相隔离,保证不同的部分不会混在一起,可使代码更加干净.整 ...
随机推荐
- VS插件之小番茄
文件源以及安装说明! http://www.youranshare.com/app/98.html
- Java基础-JVM
jvm=> java虚拟机 一.java虚拟机的生命周期: Java虚拟机的生命周期 一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序.程序开始执行时他才运行,程序结束时他就停止. ...
- 【poj2724】 Purifying Machine
http://poj.org/problem?id=2724 (题目链接) 题意 Mike有一个机器可以帮助他清理奶酪,每个奶酪由一个n位二进制数表示,机器上一共有n个按钮,每个按钮有1,0,*,其中 ...
- BZOJ1086 [SCOI2005]王室联邦
Description “余”人国的国王想重新编制他的国家.他想把他的国家划分成若干个省,每个省都由他们王室联邦的一个成 员来管理.他的国家有n个城市,编号为1..n.一些城市之间有道路相连,任意两个 ...
- 使用U盘安装mint
系统坏了,重新装的时候,硬盘甚至都没法格式化...所以,狠狠心买了块固态硬盘,123G,威刚. 想自己装Linux系统,这样用起来更方便一点,不用装虚拟机,然后再跑linux什么的.最后选了mint. ...
- debian , ubuntu 截取下拉菜单
普通情况下print键很好用的,但是,截下拉菜单的时候,就怎么按都没反应了...然后换了shutter也不行,只能在静态界面截图.所以...然后就有了下面方法. 如果不是gnome怎么办?这个担心显然 ...
- 迷宫问题(bfs)
import java.util.LinkedList; import java.util.Queue; import java.util.Stack; public class BFS { priv ...
- a[1000][1000]程序崩溃
1000 * 1000是大于65536的.如果不是需求需要,没必要开辟如此之多的空间.因为这些空间实在栈上申请的(如果是局部变量),栈的空间是有限的并且是宝贵的,所以呢,开辟太多的空间而不适用很可能会 ...
- String类的常用方法
package stringUse; public class StringUse { public static void main(String[] args) { //获取 //indexOf, ...
- Nutch的配置以及动态网站的抓取
http://blog.csdn.net/jimanyu/article/details/5619949 一:配置Nutch: 1.解压缩的nutch后,以抓取http://www.163.com/为 ...