封印术: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 ...
随机推荐
- MongoDB学习笔记——集合管理
创建集合 使用db.createCollection(name, options) 方法创建集合 name 所创建的集合名称必选! options 可选.指定有关内存大小及索引的选项 db.creat ...
- Sql Server 高频,高并发访问中的键查找死锁解析
死锁对于DBA或是数据库开发人员而言并不陌生,它的引发多种多样,一般而言,数据库应用的开发者在设计时都会有一定的考量进而尽量避免死锁的产生.但有时因为一些特殊应用场景如高频查询,高并发查询下由于数据库 ...
- Google自定义搜索引擎
本文主要介绍如何通过Google的API来定义自己的搜索引擎,并将Google搜索框嵌入到自己的web页面.另外,分析了自定义搜索引擎请求数据的url,模拟请求并获取搜索的结果. 1 写在前面 前段时 ...
- 烂泥:LVM学习之逻辑卷及卷组缩小空间
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 上一篇文章,我们学习了如何给LVM的逻辑卷及卷组扩容.这篇文章我们来学习,如何给LVM的逻辑卷及卷组缩小空间. 注意逻辑卷的缩小一定要离线操作,不能是在 ...
- 【DPDK】虚拟机开发环境配置
DPDK介绍见:www.dpdk.org 本文介绍的步骤基本适用于dpdk 1.7.0 - dpdk 2.0.0 各版本.只是setup.sh显示的菜单有一些小的不同:同样的,也适用于ubuntu更高 ...
- IE6-8中Date不支持toISOString方法
Date.prototype.toISOString方法是在ES5里添加的,ES3文档中没有,如下 这个方法在IE6/7/8中不支持,可按下面方式修复下 if (!Date.prototype.toI ...
- hdu String Problem(最小表示法入门题)
hdu 3374 String Problem 最小表示法 view code#include <iostream> #include <cstdio> #include &l ...
- Command Network
Command Network Time Limit: 1000MSMemory Limit: 131072K Total Submissions: 11970Accepted: 3482 Descr ...
- 技巧:利用 Workflow 显示附近的免费 Wi-Fi
得益于 Workflow 自 1.5.3 版本起更新的 Get Content of URL 动作,该 App 的潜力得到了极大的提升.本文分享一种有趣的用法,搜寻附近的免费 Wi-Fi 并择一显示在 ...
- Java中的流
一.Java中流的原理 流是个抽象的概念,是对输入输出设备的抽象,Java程序中,对于数据的输入/输出操作都是以“流”的方式进行.设备可以是文件,网络,内存等. 四种基本流InputStream,Ou ...