了解 Shadow DOM v1

原文地址:Understanding Shadow DOM v1javascript

Shadow DOM 的诞生是为了解决样式冲突和选择器失效的问题。它相似于一种新的 DOM 节点,或者说它能够封装了 HTML,能够用于封装一些小的组件,好比一个表单提交,咱们能够建立一个 shadow 而后独立的完整的呈现一个表单组件,而它不受外界影响。css

建立一个 shadow dom 使用 Element.attachShadow()html

<div id="host"><p>Default text</p></div>

<script> const elem = document.querySelector('#host'); // attach a shadow root to #host const shadowRoot = elem.attachShadow({mode: 'open'}); // create a <p> element const p = document.createElement('p'); // add <p> to the shadow DOM shadowRoot.appendChild(p); // add text to <p>  p.textContent = 'Hello!'; </script>

<!-- 其中不是每一种标签均可以用于建立 shadow dom 的,上面是在 div 里头建立,像 img 就没法,会报错。 而后 attachShadow() 传入一个对象参数,其余 mode: 'open'/'closed' 两种可选,这是 V1 添加的新特性,是必要属性。 当 mode: 'closed' 时,是没法经过 elem.shadowRoot 去获取 shadow dom 元素的,由于这时候它是一个 null 像上述代码的话, elem.shadowRoot 直接就指向咱们定义的变量 shadowRoot -->
复制代码

上面代码的 html 结构

样式问题java

// shadowRoot 为建立的 shadow dom 元素
shadowRoot.innerHTML = ` <p>Shadow DOM</p> <style>p {color: red;}</style>`
    
// 或者这样
shadowRoot.innerHTML = ` <p>Shadow DOM</p> <link rel="stylesheet" href="style.css">`
  
// 而后咱们是能够经过 给 shadow dom 元素设置样式经过继承去影响 shadow dom 里面的元素样式的
shadowRoot.innerHTML = ` <p>Shadow DOM</p> <style>#host {color: red;}</style>`
// 这样经过样式继承,p 标签的内容颜色也是红色的
// 能够经过 #root { all: initial; } 解决
复制代码

自定义标签也能够用 shadow dom浏览器

<my-element></my-element>
<script> class MyElement extends HTMLElement { constructor() { // must be called before the this keyword super(); // attach a shadow root to <my-element> const shadowRoot = this.attachShadow({mode: 'open'}); shadowRoot.innerHTML = ` <style>p {color: red}</style> <p>Hello</p>`; } } // register a custom element on the page customElements.define('my-element', MyElement); // 注意自定义元素的名字不能是单个单词,my-element 能够,myelement 不行! </script>
复制代码

事件触发问题app

<div id="host"></div>
 
<script> const elem = document.querySelector('#host'); const shadowRoot = elem.attachShadow({mode: 'open'}); shadowRoot.innerHTML = ` <ul> <li>One</li> <li>Two</li> <li>Three</li> <ul> `; document.addEventListener('click', (event) => { console.log(event.target); }, false); // 当你点击 shadow dom 内的元素时,它会经过冒泡触发 #host 的 div 元素,你没法知道是容器里面的具体那个元素点击了 shadowRoot.querySelector('ul').addEventListener('click', (event) => { console.log(event.target); }, false); // 这样就 ok </script>
复制代码

shadow dom v0 是谷歌浏览器的规范,如今是 v1 版本,火狐和谷歌都有版本全面支持了,苹果的嘛就只是部分支持,巨硬家的就还没支持这个特性,就目前来讲哈。dom

shadow dom 是 Web Components 的三个主要技术之一。ui

相关文章
相关标签/搜索