tnblog
首页
登录

谈谈ShadowDOM

161人阅读 2020/12/29 18:08 总访问:29357 评论:2 手机 收藏
分类: 笔记

前言:hello,各位老铁们 大家好 好久不见 我还是你们熟悉的小付
今天给大家带来的是ShadowDOM的介绍和一些案例说明。

正文:今天还是一如既往的划水,但是到了下午 项目有点问题去测试检查时发现了一个水印的问题
和我们技术大牛讨论时 叫我去看看ShadowDOM 这个玩意 说以后会好好教我其他的东西,哈哈哈

1.什么是ShadowDOM?
ShadowDOM主要解决一个文档中可能需要大量交互的多个DOM树建立和维护各自功能边界的问题。
这样说可能有点抽象,那换种说法。
  举一个常见的例子,先看下面一系列图,这是慕课网上一个视频的页面,打开chrome开发者工具查看video标签(图一)……嗯,什么都没有。但是当我们打开chrome开发者工具show shadowdom选项时(图二),我们看到video标签下的ShadowDOM结构。同时HTML支持的其他一些比如视频、音频甚至一些表单的控件,这些控件有些是由很复杂的界面组成的,其实这些界面也是用HTML+CSS写的,只是如果你不打开开发者工具的show ShadowDOM选项的话,你是无法查看到这些节点的。



ShadowDOM的意义及用法

所以这里就对ShadowDOM的思想有了一个模糊的感觉了。当我们想开发一个控件的时候,这个控件内部由一些HTML标签组成,这些元素组成DOM树的子树。这个控件可以被广泛使用,但是,每个使用这个控件的地方,都会知道这个子树的结构。当我们访问网页DOM结构的时候,这些子树都会暴露出来,给我们html文档的DOM遍历带来麻烦,而且选择器也可能会无意中改变控件的内部节点的样式,导致奇怪的问题。而事实上,我们使用控件的时候并不关心控件的内部结构,只关心控件的本身,所以需要一种方式来将内部的信息封装起来。
那么有什么办法既能将内部节点的信息封装起来,又能将这些节点给渲染出来呢?W3C提出了ShadowDOM的概念,ShadowDOM可以使一些DOM节点在特定范围内可见,而在网页DOM树中不可见,但是网页渲染的结果包含了这些节点。

一个小例子

下面我们用ShadowDOM来模仿input框开发一个输入框控件,控件左边是文字,右边是输入框,为了更好的展现ShadowDOM,输入框不采用原本的input,而是用一个可编辑内容的span代替,下面看代码,这里也有一个在线的jsbin看效果,不过还是需要浏览器支持ShadowDOM才能显示效果->传送门jsbin

<!DOCTYPE html><html><head>
    <meta charset="utf-8">
    <title>shadowDOM</title>
    <style type="text/css">
        #div { width: 300px;height: 50px;border: 1px solid #666;padding: 15px; }
    </style></head><body>
    <div id="div">这里是不显示出来的,如果你看到了,说明浏览器不支持ShadowDOM</div>
    <button>点我点我</button>
    <script type="text/javascript">
        function createShadowDOM(elem) {
            var root = elem.createShadowRoot();
            root.appendChild(createStyle());
            root.appendChild(createInputDiv("姓名","name"));
        }        function createStyle() {
            var style = document.createElement('style');
            style.textContent = 'div.input-div { height: 30px; width: 250px; }' +            '
            font.input-font { line-height: 30px;font-size: 16px;color: #495A80; margin-right: 10px;}'+            '
            span.input-area {width: 200px;height: 25px;line-height: 25px;padding-left: 5px;display:inline-block;color: #666;font-size: 16px;
            border: 1px solid #999;border-radius: 3px;}';            
            return style;
        }        function createInputDiv(font, name) {
            var inputDiv = document.createElement('div');
            inputDiv.className = 'input-div';
            inputDiv.innerHTML = "<font class='input-font'>" + font + "</font><span class='input-area' contentEditable='true' id=" + name + ">
            </span>";            
            return inputDiv;
        }

        createShadowDOM(document.querySelector("#div"));

        document.querySelector('button').addEventListener('click', function() {
            alert(document.querySelector('#div').shadowRoot.querySelector('#name').innerHTML);
        })    </script></body></html>


效果如下:

注意如果ShodowDOM显示出来的话,原先div里面的内容是不会显示出来的,如果显示出来,则说明浏览器不支持shadowDOM。

当我们使用JS代码来访问HTML文档的DOM结构的时候,通常的接口是不能直接访问到ShadowDOM子树中的节点的,只能通过特殊的接口访问:document.querySelector(‘#div’).shadowRoot.querySelector(‘#name’).innerHTML。
当然这里的代码简单的展示一下ShadowDOM的使用,如果想开发一个完美的组件的话可以将以上代码再封装一下,使用的时候直接new xxx()就可以了~

遗憾的兼容性

研究了这么些关于ShadowDOM的东西,感觉还挺有意思的。但是…可惜浏览器对它的支持并不好。以上代码我在火狐中运行就看不到效果。


以下是截图,全球的和中国的浏览器支持程度



原文地址:https://blog.csdn.net/qq_31280709/article/details/75577439

每日一笑:
1.在公园里看到一对很有爱的父女,父亲大约五十岁左右,女儿二十来岁,女儿很乖巧的给爸爸剥了一个茶叶蛋,说说什么互相开怀大笑,好温馨的家庭。但是,为什么后来他们就舌吻了呢?

2.昨天因为一件事骂儿子,说你妈妈是猪,你也是头猪。
儿子却反过来说我:爸爸你怎么这么衰,娶了一头猪,还生了一只猪!
你说你这熊孩子,这是不是找打。

3.逗B就跟常人不一样,公司老板想开除他,就对他说:你明天不用来上班了!
他说,哦,好,第二天真的没来。
结果,第三天来了。


评价
每一段旅程,都是一种领悟
排名
6
文章
6
粉丝
16
评论
8
{{item.articleTitle}}
{{item.blogName}} : {{item.content}}
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2020TNBLOG.NET
技术交流:群号677373950
欢迎加群交流技术