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:UsersasusPicturesSaved 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; 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 { 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>
原文地址:https://www.cnblogs.com/ashen1999/p/12740430.html