置顶文章:《纯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);

打印结果如下:

#document-fragment
如果你看见我了,那就是你浏览器不支持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);

实现过程如下:

  1. 创建shadow root,
  2. 在template中通过content标签和select属性获取div.shadowhtml3中的p,
  3. 将重组的template片段挂到shadow root下。

以上只是一些shadow dom的简单实现,深挖的话必定能实现更加复杂丰富的效果。


转载请标明出处
作者:myvin
原文出处:

var link=document.getElementById('link'); link.innerText=location.href;


上一篇:《鼠标滚动插件smoovejs和wowjs》

置顶文章:《纯CSS打造银色MacBook Air(完整版)》


封印术:shadow dom的更多相关文章

  1. 【shadow dom入UI】web components思想如何应用于实际项目

    回顾 经过昨天的优化处理([前端优化之拆分CSS]前端三剑客的分分合合),我们在UI一块做了几个关键动作: ① CSS入UI ② CSS作为组件的一个节点而存在,并且会被“格式化”,即选择器带id前缀 ...

  2. 使用shadow dom封装web组件

    什么是shadow dom? 首先我们先来看看它长什么样子.在HTML5中,我们只用写如下简单的两行代码,就可以通过 <video> 标签来创建一个浏览器自带的视频播放器控件. <v ...

  3. shadow dom

    初识shadow dom 我们先看个input="range"的表现: what amazing ! 一个dom能表现出这么多样式嘛? 无论是初学者和老鸟都是不肯相信的,于是在好奇 ...

  4. shadow dom 隔离代码 封装

    Shadow DOM是指浏览器的一种能力,它允许在文档(document)渲染时插入一棵DOM元素子树,但是这棵子树不在主DOM树中.   Shadow DOM 解决了 DOM 树的封装问题.     ...

  5. 纯CSS菜单样式,及其Shadow DOM,Json接口 实现

    先声明,要看懂这篇博客要求你具备少量基础CSS知识, 当然如果你只是要用的话就随便了,不用了解任何知识 完整项目github链接:https://github.com/git-Code-Shelf/M ...

  6. JavaScript 是如何工作:Shadow DOM 的内部结构 + 如何编写独立的组件!

    这是专门探索 JavaScript 及其所构建的组件的系列文章的第 17 篇. 如果你错过了前面的章节,可以在这里找到它们: JavaScript 是如何工作的:引擎,运行时和调用堆栈的概述! Jav ...

  7. Shadow DOM及自定义标签

    参考链接:点我 一.什么是Shadow DOM Shadow DOM,直接翻译的话就是 影子 DOM,可以理解为潜藏在 DOM 结构中并且我们无法直接控制操纵的 DOM 结构.类似于下面这种结构 Sh ...

  8. 理解Shadow DOM(一)

    1. 什么是Shadow DOM? Shadow DOM 如果按照英文翻译的话可以理解为 影子DOM, 何为影子DOM呢?可以理解为一般情况下使用肉眼看不到的DOM结构,那如果一般情况下看不到的话,那 ...

  9. html 中shadow DOM 的使用

    什么是shadow DOM? An important aspect of web components is encapsulation — being able to keep the marku ...

随机推荐

  1. UC 浏览器远程调试手机web网页记录

    浏览器远程调试插件有很多,本来要使用chrome浏览器的调试插件的,但是需要FQ才能使用(公司网络有限制,果断放弃),最终选择使用UC浏览器的. 其实UC官网插件使用已经介绍的很详细了,但是有几处坑需 ...

  2. Aptana studio 3前端开发编辑器推荐

    直接进入主题,先上图 这就是我Apatana studio 3的默认界面,推荐此工具的原因主要有以下几点: 1.可以集成Emmet,快速编写HTML+CSS,做到效率倍增. 2.Jquery 自动完成 ...

  3. mysql主从同步问题解决汇总

    出现问题原因:出现这个问题的原因是之前曾做过主从复制!问题:ERROR 1201 (HY000): Could not initialize master info structure; more e ...

  4. 图片代替radio

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  5. zabbix安装排错过程

    在讲安装过程之前需要先把zabbix的工作流程简单的讲一遍:zabbix是个开源监控软件,通过web才能更直观的监控我们想要监控的主机,同时,zabbix从被监控主机获取到的信息需要存放在数据库中,因 ...

  6. runv containerd 流程分析

    当runv需要启动一个容器的时候,首先需要启动containrd,作为该容器的daemon.因此,启动containerd的相关代码也是从runv/start.go开始.最终,启动containerd ...

  7. [转载]ExtJs4 笔记(3) Ext.Ajax 对ajax的支持

    作者:李盼(Lipan)出处:[Lipan] (http://www.cnblogs.com/lipan/)     本篇主要介绍一下ExtJs常用的几个对JS语法的扩展支持,包括Ajax封装,函数事 ...

  8. JAVA基础之对象的初始化

    本文主要记录JAVA中对象的初始化过程,包括实例变量的初始化和类变量的初始化以及 final 关键字对初始化的影响.另外,还讨论了由于继承原因,探讨了引用变量的编译时类型和运行时类型 一,实例变量的初 ...

  9. 第23章 SEH结构化异常处理(3)_终止处理程序

    23.3 终止处理程序 23.3.1 程序的结构 (1)框架 __try{ //被保护的代码块 …… } __finally{ //终止处理 } (2)__try/__finally的特点 ①fina ...

  10. TestLink学习一:Windows搭建Apache+MySQL+PHP环境

    PHP集成开发环境有很多,如XAMPP.AppServ......只要一键安装就把PHP环境给搭建好了.但这种安装方式不够灵活,软件的自由组合不方便,同时也不利于学习.所以我还是喜欢手工搭建PHP开发 ...