介绍shadow dom之前,首先看几个常用的标签,例子1:
<video controls autoplay name="media"> <source id="mp4" src="http://media.w3.org/2010/05/sintel/trailer.mp4" type="video/mp4"> </video> <-- 实际显示 --> <video src="a.mp4" width="480" height="360"> #shadow root <div pseudo="-webkit-media-controls"> <div pseudo="-webkit-media-controls-overlay-enclosure"> <input type="button" style="display: none;"> </div> <div pseudo="-webkit-media-controls-enclosure"> <div pseudo="-webkit-media-controls-panel" style="display: none;"> <input type="button" pseudo="-webkit-media-controls-play-button"> <input type="range" step="any" pseudo="-webkit-media-controls-timeline" max="0"> <div pseudo="-webkit-media-controls-current-time-display" style="display: none;">0:00</div> <div pseudo="-webkit-media-controls-time-remaining-display">0:00</div> <input type="button" pseudo="-webkit-media-controls-mute-button"> <input type="range" step="any" max="1" pseudo="-webkit-media-controls-volume-slider" style="display: none;"> <input type="button" pseudo="-webkit-media-controls-toggle-closed-captions-button" style="display: none;"> <input type="button" style="display: none;"> <input type="button" pseudo="-webkit-media-controls-fullscreen-button" style="display: none;"> </div> </div> </div> </video>video标签就是shadow dom结果,从上述代码可以看出,在渲染之后,显示了很多内部封装的结构。
<input type="range">,<audio></audio>也是shadow dom结构。
shadow概念:
Shadow DOM 是一个 HTML 的规范,其允许开发者封装自己的 HTML 标签、CSS 样式和 JavaScript代码。
shadow功能:
既然是封装html片段,那么功能显而易见,就是让开发人员可以创建出诸如 video这样自定义的一级标签,并且Shadow-dom 具有良好的密封性,方便复用。
Shadow-dom 是游离在 DOM 树之外的节点树,Shadow-dom 具有良好的密封性
shadow-dom Api详解
先来一段html, 以下操作基于该html
<body> <div id="notificaton"> <p>createShadowRoot</p> <button>学习</button> </div> <div id="notificatonNew"> <p>attachShadow</p> <button>学习</button> <span slot="main1" class = "slot-test"> 插槽1 </span> <span slot="main2"> 插槽2 </span> <template id="tpl"> <style> span { color:red; } </style> <!-- 这里将显示影子根节点中定义的插槽内容 --> <slot name="main1"></slot> <slot name="main2"></slot> <span>hello world</span> </template> </div> </body>1、老api createShadowRoot
//创建shadow后,notificaton元素及子节点内容不可见 const shadow = document.getElementById('notificaton').createShadowRoot();2、新的api attachShadow
const notificatonNew = document.getElementById('notificatonNew'); const shadowroot = notificatonNew.attachShadow({mode:'open'});说明:attachShadow参数含义
mode: 一个指定Shadow DOM封装模式的字符串,可以是下列之一:
open指定为开放的封装模式。
closed指定为关闭的封装模式。
给影子dom添加内容:
通过innerHTML添加:
shadow.innerHTML = ` <style>:host { font-weight: bold; color:blue; }</style> <p class = "shadow-inside-node">Lorem ipsum dolor sit amet.</p> <content select="span"> Lorem ipsum dolor sit amet. <div>test-div</div> </content> `说明://:host伪选择器,通过:host可以选择shadow
通过模板添加:
//'tpl'是上面template的id shadowroot.appendChild(document.getElementById('tpl').content.cloneNode(true));扩展功能:插槽slot的使用
shadow中可以使用插槽,在要创建shadow dom的元素内先定义好插槽,然后在模板中使用插槽,渲染时会替换插槽。
shadowroot.innerHTML = ` <style> :host { color: blue; } </style> <slot name="main1"></slot> <slot name="main2"></slot> <slot> `在模板中使用
<div id="notificatonNew"> <p>attachShadow</p> <button>学习</button> <span slot="main1" class = "slot-test"> 插槽1 </span> <span slot="main2"> 插槽2 </span> <template id="tpl"> <style> span { color:red; } </style> <!-- 这里将显示影子根节点中定义的插槽内容 --> <slot name="main1"></slot> <slot name="main2"></slot> <span>hello world</span> </template> </div>slot属于较新的api,存在兼容性问题,尽量不要在生产环境使用
参考:https://www.imweb.io/topic/5593cc62799539f821cd2541
https://blog.csdn.net/Aijn_faluts/article/details/88658884
https://www.cnblogs.com/yangguoe/p/8486046.html
https://www.jianshu.com/p/9293cac60920
https://developer.mozilla.org/zh-CN/docs/Web/API/Element/attachShadow