封印术:shadow dom
置顶文章:《纯CSS打造银色MacBook Air(完整版)》
上一篇:《鼠标滚动插件smoovejs和wowjs》
作者主页:myvin
博主QQ:851399101(点击QQ和博主发起临时会话)
::selection{
background:blue;
color:red;
}
Tip: 为保证良好的体验,请使用chrome打开查看。(笔者使用的chrome版本为48.0.2564.97 (64-bit))。
1.input[type = "date"]
1.input[type = "date"]内部实现
在开始shadow dom之前,先看一个html原生组件:
<input class="test1" type="date" value="2222-2-2">
这是一个时间组件,效果如下:
这里是默认的日期组件样式
该原生date组件有下拉箭头,可以清除内容,展开可以选择日期,而我们实现的这一系列功能只是通过一个input[type="date"]这样的标签,那这里一定会有其他的实现。
In fact,该组件是已经被封装好的。如果直接用浏览器查看源码,也只有<input type="date" value="2022-02-02"/>这么一句。为了查看内部实现,在chrome的setting中勾选上Show user agent shadow DOM选项,这时候再查看该元素,会看到这样的结构:
<input class="test1" type="date" value="2022-02-02"/>
#shadow-root
<div pseudo="-webkit-datetime-edit" id="date-time-edit" datetimeformat="yy/M/d">
<div pseudo="-webkit-datetime-edit-fields-wrapper">
<span role="spinbutton" aria-valuetext="空白" aria-valuemin="1" aria-valuemax="275760" aria-help="年" pseudo="-webkit-datetime-edit-year-field"> 年 </span>
<div pseudo="-webkit-datetime-edit-text">/</div>
<span role="spinbutton" aria-valuetext="空白" aria-valuemin="1" aria-valuemax="12" aria-help="月" pseudo="-webkit-datetime-edit-month-field">月</span>
<div pseudo="-webkit-datetime-edit-text">/</div>
<span role="spinbutton" aria-valuetext="空白" aria-valuemin="1" aria-valuemax="31" aria-help="日" pseudo="-webkit-datetime-edit-day-field">日</span>
</div>
</div>
</input>
该结构即为其内部实现结构。而之后要聊的shadow dom即可以实现这样的封装。
2.input[type = "date"]修改样式
上述提到了input[type = "date"],那就顺便简单看看如何来修改其样式。
在上述的结构上可以看到有9个伪元素,通过这9个伪元素即可修改其样式:
::-webkit-datetime-edit – 编辑区域
::-webkit-datetime-edit-fields-wrapper – 年月日区域
::-webkit-datetime-edit-text – 日期分割线
::-webkit-datetime-edit-year-field – 年
::-webkit-datetime-edit-month-field – 月
::-webkit-datetime-edit-day-field – 日
::-webkit-clear-button - 箭头前面的X号
::-webkit-inner-spin-button – 上下箭头
::-webkit-calendar-picker-indicator – 下拉展开箭头
详细情况可以在调试中自行查看,下面只是简单粗暴的设置一些样式示范一下样式修改:
CSS:
::-webkit-datetime-edit{
padding: 5px;
background-color: rgba(255,0,0,.3);
}
::-webkit-datetime-edit-fields-wrapper{
border: 1px solid black;
}
::-webkit-datetime-edit-text{
color: transparent;
}
::-webkit-datetime-edit-text::before{
color: red;
content: '-';
}
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-year-field{
color: blue;
}
::-webkit-clear-button,
::-webkit-inner-spin-button,
::-webkit-calendar-picker-indicator{
padding: 10px;
}
结果如下:
这里是修改后的日期组件样式
input[class="test2"]::-webkit-datetime-edit{ padding: 5px; background-color: rgba(255,0,0,.3);}input[class="test2"]::-webkit-datetime-edit-fields-wrapper{ border: 1px solid black;}input[class="test2"]::-webkit-datetime-edit-text{ color: transparent;}input[class="test2"]::-webkit-datetime-edit-text::before{ color: red; content: '-';}input[class="test2"]::-webkit-datetime-edit-month-field,input[class="test2"]::-webkit-datetime-edit-day-field,input[class="test2"]::-webkit-datetime-edit-year-field{ color: blue;}input[class="test2"]::-webkit-clear-button,input[class="test2"]::-webkit-inner-spin-button,input[class="test2"]::-webkit-calendar-picker-indicator{ padding: 10px;}
2.shadow dom是什么
shadow dom是浏览器的一种技术,可以实现让dom独立于原有的dom tree,这样一来就无需担心id污染、样式污染、js污染,外部的css并不会影响这个dom,就仿佛是一个影子shadow。并且可以用来隐藏封装细节,就像上述原生的input[type = "date"]一样,从而可以用来实现web compnents。
shadow dom的这种封装功能,就像把九尾九喇嘛封印在鸣人体内一样,九尾在里面怎么折腾在外面是看不到的,但是鸣人一爆发,体外的红色查克拉就一点一点开始蔓延~我转过我的脸不让你看见~深藏的暗涌已经越来越明显~
3.<content>和<template>
在进行shadow dom之前,先来温故两个标签,<content>和<template>。
1.关于<content>先引用一段MND上的一句解释:
The HTML element is used inside of Shadow DOM as an insertion point. It is not intended to be used in ordinary HTML. It is used with Web Components.
<content>标签可以在shadow dom中作为一个插入点,然后再结合select属性来获取相关内容,从而实现后续操作。
2.<template>标签顾名思义是一个模板标签,它可以用来存储数据,但是默认不会显示,需要处理其中的内容数据时可以通过js来实现,所以它的第一个特点就是不可见。见如下结构:
<p>下面有一个template标签,浏览器支持的话是看不见的</p>
<template class="test3"><p>如果你看见我了,那就是你浏览器不支持template标签。</p></template>
结果如下:
下面有一个template标签,浏览器支持的话是看不见的
如果你看见我了,那就是你浏览器不支持template标签。
第二个特点是无法通过childNodes访问子节点。
这里在浏览器里打印如下:
console.log(document.querySelector('.test3').childNodes);
结果为[]。
如果要访问<template>下的子节点,需要通过content属性。这里在浏览器里打印:
console.log(document.querySelector('.test3').content);
打印结果如下:
如果你看见我了,那就是你浏览器不支持template标签。
3.shadow dom实现
shadow dom的实现通过creatShadowRoot()方法来实现。
先给出一段HTML和js。
html:
<div class="shadowhtml">
<p>猴年大吉,万事如意,猴赛雷!</p>
</div>
js:
document.querySelector('.shodowhtml').creatShadowRoot();
js中,先获取该div.shadowhtml,然后创建shadow root,这个shadow root正如文章最开始input下的那个#shadow-root。
下面分别是没有shadow化和shadow化的结果:
1.这是没有shadow化的结果:
猴年大吉,万事如意,猴赛雷!
2.这是shadow化的结果:
这是shadow化的,如果你看见我了,麻烦请使用最新的chrome,大恩不言谢。
document.querySelector('.shadowhtml').createShadowRoot();
创建了shadow root后,div.shadowhtml里面的内容不显示,即shadow dom的父元素不显示。
接下来,尝试给shadow root写内容。这里只修改js如下:
document.querySelector('.shadowhtml').createShadowRoot().textContent = "恭喜发财,鸿运当头!";
显示结果如下:
这是shadow化的,如果你看见我了,麻烦请使用最新的chrome,大恩不言谢。
document.querySelector('.shadowhtml2').createShadowRoot().textContent = "恭喜发财,鸿运当头!";
可以看到,shadow root里面的内容替换掉了shadow root父元素的内容。因此,我们可以将一些数据内容在shadow root下显示出来。下面,结合<content>和<template>标签,从shadow root父元素中获取内容数据,然后显示出来。
html结构和js如下:
html结构:
<div class="shadowhtml3">
<p class="shadowp">猴年大吉,万事如意,猴赛雷!</p>
</div>
<template class="tpl">
<span>祝大家<content select=".shadowp"></content></span>
</template>
js:
<script type="text/javascript">
document.querySelector('.shadowhtml3').createShadowRoot().appendChild(document.querySelector('.tpl').content);
</script>
结果如下:
猴年大吉,万事如意,猴赛雷!
祝大家
document.querySelector('.shadowhtml3').createShadowRoot().appendChild(document.querySelector('.tpl').content);
实现过程如下:
- 创建shadow root,
- 在template中通过content标签和select属性获取
div.shadowhtml3中的p, - 将重组的template片段挂到shadow root下。
以上只是一些shadow dom的简单实现,深挖的话必定能实现更加复杂丰富的效果。
转载请标明出处
作者:myvin
原文出处:
var link=document.getElementById('link'); link.innerText=location.href;
上一篇:《鼠标滚动插件smoovejs和wowjs》
置顶文章:《纯CSS打造银色MacBook Air(完整版)》
封印术:shadow dom的更多相关文章
- 【shadow dom入UI】web components思想如何应用于实际项目
回顾 经过昨天的优化处理([前端优化之拆分CSS]前端三剑客的分分合合),我们在UI一块做了几个关键动作: ① CSS入UI ② CSS作为组件的一个节点而存在,并且会被“格式化”,即选择器带id前缀 ...
- 使用shadow dom封装web组件
什么是shadow dom? 首先我们先来看看它长什么样子.在HTML5中,我们只用写如下简单的两行代码,就可以通过 <video> 标签来创建一个浏览器自带的视频播放器控件. <v ...
- shadow dom
初识shadow dom 我们先看个input="range"的表现: what amazing ! 一个dom能表现出这么多样式嘛? 无论是初学者和老鸟都是不肯相信的,于是在好奇 ...
- shadow dom 隔离代码 封装
Shadow DOM是指浏览器的一种能力,它允许在文档(document)渲染时插入一棵DOM元素子树,但是这棵子树不在主DOM树中. Shadow DOM 解决了 DOM 树的封装问题. ...
- 纯CSS菜单样式,及其Shadow DOM,Json接口 实现
先声明,要看懂这篇博客要求你具备少量基础CSS知识, 当然如果你只是要用的话就随便了,不用了解任何知识 完整项目github链接:https://github.com/git-Code-Shelf/M ...
- JavaScript 是如何工作:Shadow DOM 的内部结构 + 如何编写独立的组件!
这是专门探索 JavaScript 及其所构建的组件的系列文章的第 17 篇. 如果你错过了前面的章节,可以在这里找到它们: JavaScript 是如何工作的:引擎,运行时和调用堆栈的概述! Jav ...
- Shadow DOM及自定义标签
参考链接:点我 一.什么是Shadow DOM Shadow DOM,直接翻译的话就是 影子 DOM,可以理解为潜藏在 DOM 结构中并且我们无法直接控制操纵的 DOM 结构.类似于下面这种结构 Sh ...
- 理解Shadow DOM(一)
1. 什么是Shadow DOM? Shadow DOM 如果按照英文翻译的话可以理解为 影子DOM, 何为影子DOM呢?可以理解为一般情况下使用肉眼看不到的DOM结构,那如果一般情况下看不到的话,那 ...
- html 中shadow DOM 的使用
什么是shadow DOM? An important aspect of web components is encapsulation — being able to keep the marku ...
随机推荐
- XShell上传、下载文件(使用sz与rz命令)!
rz,sz是Linux/Unix同Windows进行ZModem文件传输的命令行工具.优点就是不用再开一个sftp工具登录上去上传下载文件. sz:将选定的文件发送(send)到本地机器rz:运行该命 ...
- c++基础回顾
#include <iostream> #include <vector> #include <string> int main(int argc, const c ...
- tmpFile.renameTo(classFile) failed 错误
突然的出现了这个tmpFile.renameTo(classFile) failed 错误. 也许是我删掉了tomcat里面的webapps 中的项目,而通过debug部署,而出现了这个问题. 一开始 ...
- Linux系统命令查询软件包
转载自:http://blog.chinaunix.net/uid-346158-id-2131252.html,http://www.jb51.net/os/RedHat/1102.html, 一. ...
- Linux Purify命令
一.简介 在C/C++的软件开发中,没有任何一种工具可以让你的应用程序避免引入内存问题,但是我们可以使用诸如Purify这样的工具对已经做好了的程序进行内存问题的检查.Purify的强大之处是可以找到 ...
- JS判断浏览器类型及版本
浏览器 ie firefox opera safari chrome 分类: 一路辛酸---JavaScript 你知道世界上有多少种浏览器吗?除了我们熟知的IE, Firefox, Opera, S ...
- Maximum Subsequence Sum(接上篇)
Given a sequence of K integers { N1, N2, ..., NK }. A continuous subsequence is defined to be { Ni, ...
- C# 遍历枚举类
framework 4.0 环境下 方法 定义枚举类 判断枚举类中是否存在,若存在则输出 例子: Defined.QrCode.QrCodeType type;//枚举类 if (!Enum.TryP ...
- 《TCP/IP详解 卷一》读书笔记-----TCP超时重传
1.TCP提供的是可靠传输,它通过接收方发送一个确认报文ACK来提供这种可靠性.但是数据报文和确认报文都可能会丢失,所以TCP会给发出的数据报文设置一个时间,如果超时了则进行重传 2.Karn's A ...
- 《TCP/IP 详解 卷一》读书笔记-----Ping&Traceroute
1.ping是用于测试对方主机是否可达的命令,其实本质上就是echo类型的ICMP报文.同时,ping还能用于计算RTT(round-trip time),即两台主机间的往返时延. 2.随着网络安全意 ...