shadow DOM
什么是shadow DOM?
将一组隐藏的、独立的DOM结构附加到某个元素上。比如在video元素的shadow DOM上,就隐藏了许多对视频控制的按钮和控制器等。
shadow host:一个常规的DOM节点,shadow DOM 会被附加到这个节点上
shadow tree:shadow DOM 内部的DOM tree
shadow root:shadow tree的根节点
shadow boundary:shadow tree结束的地方,也就是常规DOM开始的地方
和操作常规DOM一样,可以用相同的方式操作Shadow DOM ,比如为其添加子节点,设置属性、样式等。不同的是,shadow DOM 始终不会影响其外部的元素,
除了:focus-within(是一个css伪类,表示一个元素获得焦点,或该元素的后代获得焦点)
基本用法
Element.attachShadow() :
将一个shadow root添加到某个元素上,接收一个对象作为参数:{mode: ‘open/closed‘}。当为open时允许以js的方式操作shadow DOM,closed时不允许外部对其进行操作
如果想将一个shadow DOM 附加到常规DOM上,就可以在常规DOM的构造函数中:
let shadow = this.attachShadow({mode: ‘open‘});之后就可以通过js对其进行操作,如下
let img = document.createElement(‘img‘); shadow.appendChild(img);
以下为MDN中的示例:shadow dom包含一个图片icon和一个隐藏的info,当图片icon获得焦点时info显示,内容为说明信息
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body><!--在页面中直接使用 -->
<popup-info img="C:\Users\asus\Pictures\Saved Pictures" text="Your card validation code (CVC) is an extra security feature — it is the last 3 or 4 numbers on the back of your card.">
</body>
<script> // 创建一个常规DOM,用来添加shadow dom
class popUpInfo extends HTMLElement{
constructor(){
super(); // 创建一个shadow root
var shadow = this.attachShadow({mode: ‘open‘}); // 创建三个span。并未它们赋予class属性和值
var wrapper = document.createElement(‘span‘);
wrapper.setAttribute(‘class‘, ‘wrapper‘);
var icon = document.createElement(‘span‘);
icon.setAttribute(‘class‘, ‘icon‘);
icon.setAttribute(‘tabindex‘, 0);
var info = document.createElement(‘span‘);
info.setAttribute(‘class‘, ‘info‘); // 将当前元素上的text属性值赋值给info的内容,info就是用来显示图片的说明信息
var text = this.getAttribute(‘text‘);
info.textContent = text;
// 将当前元素的img属性值获取,创建一个img元素,放到icon中
var imgUrl;
if (this.hasAttribute(‘img‘)) {
imgUrl = this.getAttribute(‘img‘);
}else{
imgUrl = ‘img/default.png‘;
}
var img = document.createElement(‘img‘);
img.src = imgUrl;
icon.appendChild(img);// 为 shadow DOM 添加一些 CSS 样式
var style = document.createElement(‘style‘);
style.textContent =
`.wrapper {
position: relative;
}
.info {
font-size: 0.8rem;
width: 200px;
display: inline-block;
border: 1px solid black;
padding: 10px;
background: white;
border-radius: 10px;
opacity: 0;
transition: 0.6s all;
position: absolute;
bottom: 20px;
left: 10px;
z-index: 3;
}
img {
width: 1.2rem;
}
.icon:hover + .info, .icon:focus + .info {
opacity: 1;
}`; // 将样式和wrapper添加给shadow
shadow.appendChild(style);
shadow.appendChild(wrapper); // wrapper中包含icon和info
wrapper.appendChild(icon);
wrapper.appendChild(info);
}
}
// 定义常规DOM
customElements.define(‘popup-info‘, popUpInfo);
</script>
</html>