封印术: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 ...
随机推荐
- MySQL数据库初识(一)
MySQL是一种免费的小型关系型数据库,与Linux.Apache/Nginx.PHP一起组成了WEB开发的黄金搭档. MySQL是C/S(客户端/服务端)体系结构的软件,而在开发中,PHP承担起了客 ...
- linux安装pylab
在linux下就是一句话 sudo apt-get install python-matplotlib 该工具包含了pylab, numpy,scipy和matplotlib四个工具包 对matplo ...
- PPT制作教程:如何制作ppt
PowerPoint(PPT)是专门用于制作演示文稿(俗称幻灯片).广泛运用于各种会议.产品演示.学校教学等.学会如何制作ppt,成为提升工作效 率的好帮手.PPT包含有很多的功能,我们可以根据个人喜 ...
- 烂泥:KVM使用裸设备配置虚拟机
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 何谓裸设备?百度百科显示: 裸设备(raw device),也叫裸分区(原始分区),是一种没有经过格式化,不被Unix通过文件系统来读取的特殊块设备文件 ...
- 烂泥:KVM虚拟机的关机与开启
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 我们在开启与关闭KVM虚拟机时,一般是通过start.shutdown.reboot等命令来进行.但是有时候我们会发现在使用shutdown.reboo ...
- 详解apache的allow和deny
今天看了一篇关于apache allow,deny的文章收获匪浅,防止被删,我直接摘过来了,原文地址!!! !http://www.cnblogs.com/top5/archive/2009/09/2 ...
- 【OpenGL】交互式三次 Bezier 曲线
1. 来源 三次贝塞尔曲线就是依据四个位置任意的点坐标绘制出的一条光滑曲线 2. 公式 3. 实现 #include <iostream> #include <math.h> ...
- jquery 地址栏链接与a标签链接匹配 特效代码总结(二)
如题所述,当出现这样的功能,点击某个链接后,给跳转后的该链接地址添加样式,通过添加class为current来增加特殊样式. 如图所示:点击HTML+css3跳转后,给其添加如图样式: js代码如下: ...
- js原生捕鱼达人(二)
昨天写到构造炮弹,有点小bug不知道大家发现没有,今天继续昨天的步骤 7>构造炮弹 思路和前面都是一样一样的 注意构造函数中需要考虑的属性 和 构造函数的原型上面的方法 <sc ...
- 自定义表单验证$setValidaity