关于影子(shadow)DOM
经常写video,audio等html元素在带的控制条或者模块,但是这这些模块哪里来的用什么实现的
发现步骤
进入setttins, 在elements里勾选
如此打开新世界的大门
隐藏有点深刻,难以发现。
那什么是影子DOM
- 影子dom这个东西的存在,主要解决dom树建立时能够实现维护自身边界的问题。这么说有点像vue的scope保证自身不会被外来修饰入侵或者污染。
- 影子dom将对应的dom信息隐藏起来依然能在html文档里渲染出来。但不能通过普通的js方法获取到dom信息
- 影子dom事件捕获遵从常规dom事件,在影子dom内部依然传递,同时也遵从事件冒泡,向整个文档的dom上传递事件。
影子树和文档
创建影子树
通过createShadowRoot创建影子树root节点
<!DOCTYPE html>
<html>
<head><title>影子dom</title><link rel="dns-prefetch" href="//dfhs.tanx.com"><style>.box {height: 80px;width: 80px;background-color: red;}</style>
</head>
<body><div id="box" class="box"></div>
</body>
<script>var $box = document.getElementById('box');var shadowRoot = $box.createShadowRoot(); // 获得root//var showRoot = $box.webkitGetShadowRoot() // webkit 支持var children = document.createElement('div');children.setAttribute('style', 'height: 40px; width: 40px; background-color: blue');shadowRoot.appendChild(children);
</script>
</html>
效果图
再给影子树节点添加css时不能用过class或者元素选择来添加,否则无效果
<!DOCTYPE html>
<html>
<head><title>影子dom</title><link rel="dns-prefetch" href="//dfhs.tanx.com"><style>.box {height: 80px;width: 80px;background-color: red;}.children {height: 40px;width: 40px;background-color: blue;}div {height: 40px;width: 40px;background-color: blue;}</style>
</head>
<body><video src="test.mp4" height="200px" controls></video><audio src="mp3.mp3" controls></audio><canvas></canvas><div id="box" class="box"></div>
</body>
<script>var $box = document.getElementById('box');var shadowRoot = $box.createShadowRoot(); // 获得root//var showRoot = $box.webkitGetShadowRoot() // webkit 支持var children = document.createElement('div');children.setAttribute('class', 'children');shadowRoot.appendChild(children);
</script>
</html>
通过class选择dom时需要将style也放入影子节点里
<script>var $box = document.getElementById('box');var shadowRoot = $box.createShadowRoot(); // 获得root//var showRoot = $box.webkitGetShadowRoot() // webkit 支持var children = document.createElement('div');children.setAttribute('class', 'children')shadowRoot.innerHTML += '<style>.children { height: 40px; width: 40px; background-color: blue;}</style>';shadowRoot.appendChild(children);
</script>
不能直接获得影子DOM
通过js常规方法不能直接获取到dom节点
var $box = document.getElementById('box');var shadowRoot = $box.createShadowRoot(); // 获得root//var showRoot = $box.webkitGetShadowRoot() // webkit 支持var children = document.createElement('div');children.setAttribute('class', 'children');children.setAttribute('id', 'children');shadowRoot.appendChild(children);// 获得影子dom// 通过idvar getShadowRootById = document.getElementById('children');console.log(getShadowRootById)// 通过节点选择console.log('---------------')var getShadowRootByDomBox = document.body.firstChild.nextSibling; // 获得到box//var getShadowRootByDom = getShadowRootByDomBox.firstChildvar getShadowRootByDom = getShadowRootByDomBox.firstElementChild;console.log(getShadowRootByDom)
影子dom事件绑定
在createElement时拿到的元素,添加addEventListener事件
var $box = document.getElementById('box');var shadowRoot = $box.createShadowRoot(); // 获得root//var showRoot = $box.webkitGetShadowRoot() // webkit 支持var children = document.createElement('div');children.setAttribute('class', 'children')shadowRoot.innerHTML += '<style>.children { height: 40px; width: 40px; background-color: blue;}</style>';shadowRoot.appendChild(children);children.addEventListener('click', function(e) {console.log(e)})
通过template完整的操纵影子dom
template也是documentfragment
<!DOCTYPE html>
<html>
<head><title>影子dom</title><link rel="dns-prefetch" href="//dfhs.tanx.com"><style>.box {height: 80px;width: 80px;background-color: red;}.children {height: 40px;width: 40px;background-color: blue;}</style>
</head>
<body><div id="box" class="box"></div><div class="box-test"></div><template class="root-tlp"><style>.test-ctn {color: white;}</style><div><div class="test-ctn" id="test">测试</dt></div><script>document.addEventListener('click', function(e) {console.log(e)})</script></template>
</body>
<script>var $box = document.getElementById('box');var shadowRoot = $box.createShadowRoot(); // 获得rootvar children = document.createElement('div');children.setAttribute('class', 'children')shadowRoot.innerHTML += '<style>.children { height: 40px; width: 40px; background-color: blue;}</style>';var template = document.querySelector('.root-tlp');shadowRoot.appendChild(template.content);
</script>
</html>
当然绑定事件同样有输出
利用content元素select属性将目标内容匹配到template中指定位置,并且目标内容只能在影子元素里
<!DOCTYPE html>
<html>
<head><title>影子dom</title><link rel="dns-prefetch" href="//dfhs.tanx.com"><style>.box {height: 160px;width: 160px;background-color: red;}.children {height: 80px;width: 80px;background-color: blue;}.test-content {background-color: yellow;}</style>
</head>
<body><div id="box" class="box"><div class="test-content">我接着测试</div></div><template class="root-tlp"><style>.test-ctn {color: white;}</style><div><div class="test-ctn" id="test">测试</dt></div><content select=".test-content"></content></template>
</body>
<script>var $box = document.getElementById('box');var shadowRoot = $box.createShadowRoot(); // 获得rootvar children = document.createElement('div');var template = document.querySelector('.root-tlp');shadowRoot.appendChild(document.importNode(template.content, true));document.addEventListener('click', function() {console.log('test-content')})
</script>
</html>
这种方式改变文档流顺序还能直接获得dom节点和绑定事件
CSS 选择器:
:host, :host(), :host-context()
:host
<template class="root-tlp"><style>.test-ctn {color: white;}:host {font-weight: bold;}</style><div><div class="test-ctn" id="test">测试</dt></div><content select=".test-content"></content></template>
:host()选择器,选择影子dom宿主元素
<body><div id="box" class="box"><div class="test-content">我接着测试</div></div><template class="root-tlp"><style>.test-ctn {color: white;}:host {font-weight: bold;}:host(.box) {color: blue;}</style><div><div class="test-ctn" id="test">测试</dt></div><content select=".test-content"></content></template>
</body>
:host-context()与后代选择器表达式一起使用,以仅选择特定祖先内部的自定义元素的实例
<!DOCTYPE html>
<html>
<head><title>影子dom</title><link rel="dns-prefetch" href="//dfhs.tanx.com"><style>.box {height: 160px;width: 160px;}.children {height: 80px;width: 80px;}</style>
</head>
<body><div id="box" class="test"><div class="box-content" id="box-content"><div class="box-ctn">213</div></div></div><template class="root-tlp"><style>.test-ctn {color: white;}:host {font-weight: bold;}:host(.box-content) {color: blue;background-color:red;}:host-context(.test) {height: 300px;background-color: blueviolet}</style><div><div class="test-ctn" id="test">测试</dt></div><content select=".box-ctn"></content></template>
</body>
<script>var $box = document.getElementById('box-content');var shadowRoot = $box.createShadowRoot(); // 获得rootvar children = document.createElement('div');var template = document.querySelector('.root-tlp');shadowRoot.appendChild(document.importNode(template.content, true));
</script>
</html>
关于影子(shadow)DOM相关推荐
- [html] 说说你对影子(Shadow)DOM的了解
[html] 说说你对影子(Shadow)DOM的了解 web component的API,用来给组件创建子DOM树,就像楼上说的,不受外部style影响,外部通过选择器查询也不会查到里面来.它有两种 ...
- 理解Shadow DOM
1. 什么是Shadow DOM? Shadow DOM 如果按照英文翻译的话可以理解为 影子DOM, 何为影子DOM呢?可以理解为一般情况下使用肉眼看不到的DOM结构,那如果一般情况下看不到的话,那 ...
- Shadow DOM及自定义标签
参考链接:点我 一.什么是Shadow DOM Shadow DOM,直接翻译的话就是 影子 DOM,可以理解为潜藏在 DOM 结构中并且我们无法直接控制操纵的 DOM 结构.类似于下面这种结构 Sh ...
- Shadow DOM的理解
Shadow DOM的理解 Shadow DOM是HTML的一个规范,其允许在文档document渲染时插入一颗DOM元素子树,但是这棵子树不在主DOM树中,Shadow DOM如果按照英文翻译的话可 ...
- Shadow DOM系列1-简介
为什么80%的码农都做不了架构师?>>> 英文链接:Shadow DOM: Introduction, 26 AUGUST 2013 on Web Components, Sh ...
- shadow dom的作用和用法详解(createShadowRoot, attachShadow)
相信shadow dom很多前端开发工作者都遇到过,它是web component的一部分.不过对于shadow dom很多人并不深入了解,只晓得是影子dom结构,那么到底什么是shadow dom的 ...
- shadow dom一个最简单的例子
本文资料来自stackoverflow:https://stackoverflow.com/questions/34119639/what-is-shadow-root/34119775#341197 ...
- html页面和Chrome开发者工具elements界面不一致的一个可能原因:没有在Chrome开发者工具里打开对Shadow DOM显示的支持
一个例子: 虽然UI上input field里显示的是Jerry,但是Chrome开发者工具里面并没有显示出来. 注意上图最下方,显示的input后面有#shadow-root.div. 打开sett ...
- [译] 用 Shadow DOM v1 和 Custom Elements v1 实现一个原生 Web Component
原文地址:Make a Native Web Component with Custom Elements v1 and Shadow DOM v1 原文作者:Pearl Latteier 译文出自: ...
最新文章
- 备忘录吕吕没有备忘录十新建_一份备忘单,可帮助您记住CSS自定义属性
- RDKit:计算不同分子或构象之间的RMSD
- Promise 简介
- vivado SOC——hello word(上)建立SOC系统
- Leetcode-最长回文子串(5)
- XML学习笔记01【xml_基础、xml_约束】
- linux安装mysql出现Could NOT find Curses (missing CURSES_LIBRARY CURSES_INCLUDE_PATH),提示解决方法...
- 剑指offer(04)重建二叉树
- import qs from qs 安装_Python 导包难道你只会个 import 吗?
- jpa 跨表_JPA的多表复杂查询
- android 7使用litepal,android数据库litepal使用记录
- 五家共井 穷举法_测井曲线代码一览表
- 解决ubuntu12.04 virtubox xp 有道词典发音问题
- 解决ThinkPad S3-440无法睡眠问题
- 六、利用ESP32搭建网络服务器(一)
- [SSL_CHX][2021-8-18]角谷猜想
- Automated Installations of Multiple RHEL/CentOS 7 Distributions using PXE Server and Kickstart Files
- JAVA删除pdf空白页_如何编辑PDF文件,如何删除PDF文档中的空白页
- Q3亏损收窄预计Q4季度实现盈利,趣头条走上盈利分水岭靠什么?
- fpga实现dds和混频器
热门文章
- 北斗三号短报文功能手机成果发布,前景如何?
- 用安卓手机远程管理linux,支持SSH密钥登录
- Redis的那些最常见面试问题
- 京东数据化运营(五)— 行业分析篇
- JavaWeb frontTools / fronttool / web design
- 如何查看建筑设计图纸呢?CAD小白如何实现CAD快速看图?
- android实现地图api公交线路查询,android实现查询公交车还有几站的功能
- kali linux 2020虚拟机镜像的安装(详细安装过程及安装包百度云连接)
- java五子棋联网对战,毕业设计-- 用JAVA实现五子棋网络对战系统
- 第十一届北京师范大学程序设计竞赛(网络同步赛)+A. BNU ACM校队时间安排表