HTML5技术

封印术:shadow dom - myvin

字号+ 作者:H5之家 来源:博客园 2016-02-19 13:00 我要评论( )

置顶文章:《纯CSS打造银色MacBook Air(完整版)》上一篇:《鼠标滚动插件smoovejs和wowjs》 作者主页:myvin 博主QQ:851399101(点击QQ和博主发起临时会话) Tip: 为保证良好的体验,请使用chrome打开查看。(笔者使用的chrome版本为48.0.2564.97 (64-bit)

置顶文章:《纯CSS打造银色MacBook Air(完整版)》 上一篇:《鼠标滚动插件smoovejs和wowjs》

作者主页:myvin
博主QQ:851399101(点击QQ和博主发起临时会话)


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; }

结果如下:

这里是修改后的日期组件样式

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,大恩不言谢。

创建了shadow root后,div.shadowhtml里面的内容不显示,即shadow dom的父元素不显示。

接下来,尝试给shadow root写内容。这里只修改js如下:

document.querySelector('.shadowhtml').createShadowRoot().textContent = "恭喜发财,鸿运当头!";

显示结果如下:

这是shadow化的,如果你看见我了,麻烦请使用最新的chrome,大恩不言谢。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • css3 text-shadow字体阴影讲解 - danran68

    css3 text-shadow字体阴影讲解 - danran68

    2016-10-25 15:00

  • 神秘的 shadow-dom 浅析 - ChokCoco

    神秘的 shadow-dom 浅析 - ChokCoco

    2016-07-30 11:00

  • 利用jquery实现百度新闻导航菜单滑动动画 - ShadowFiend

    利用jquery实现百度新闻导航菜单滑动动画 - ShadowFiend

    2015-10-17 10:29

网友点评
x