Shadow DOM encapsulates DOM sub tree and their style. It creates a boundary, so that it maintains a separation from the main document. This avoids leaking of styles from the main DOM to shadow DOM and visa versa. Markup is also protected as they cannot be accessed through standard selectors. In past people have used iframe to achieve short of similar feature, but that comes with extra baggage as iframe is mainly designed to host separate web page. Also interaction between iframe and its host may not be straight forward.
How to Create Shadow DOM
var host = document.createElement('div');
var root = host.createShadowRoot();
root.innerHTML = "<h1>This is shadow DOM</h1>";
Terminologies
- Light DOM - DOM which is not within shadow DOM is called Light DOM. In other words it the DOM which people refer prior to concept of shadow..
- Logicl DOM - Together Light DOM and Shadow DOM are referred as logical DOM.
- Shadow Host - Its the element in the Light DOM which host shadow DOM
- shadow-root - This contains the shadow dom, and will be a child to the main DOM. Anything underneath this cannot be accessed through standard selector like this (document.querySelector('h1')),rather you have to use selector on shadow root object. All following methods are supported shadow root
- getElementById()
- getElementByClassName()
- getElementByTagName()
- getElementByTagNameNS()
- querySelector()
- querySelectorAll()
java script
js within shadow dom is not encapsulated. js defined in template tag will still be attached to windows object, but since markup will not be accessible across shadow boundary through standard selector, chances of accidentally impacting mark up across boundary is very less.
Content Insertion Points
Content tag provides a way through which mark up defined in the Light DOM can be distributed in Shadow DOM. You can provide selector that specify the markup which you want to distribute. You can have multiple content tag and the first content tag which match selector and is not already inserted will display it. If you create empty content tag, it will insert everything which is not already inserted. If there is no empty content tag, then only selected markup will be displayed, rest will be ignored.
Content create an insertion point. Elements inserted (which comes from Light DOM) at this insertion point is called distributed node. Distributed nodes are just displayed at the insertion point and they are not actually inserted into the Shadow DOM. Distributed node remains part of Light DOM and you can still user standard selector (document.querySelector('h1')) for distributed node, whereas selector on the root (root.querySelector('content div')) will not return anything.
Following api are provided in order to access distributed node as well as insertion point
getDistributedNode
root.querySelector('content').getDistributedInsertionNode()
getDistributedInsertionPoints Get list of all content tag where light dom is inserted
document.querySelector('h1').getDistributedInsertionPoints()
Supported Content Selector
<content select="h1"> match all h1 element from light DOM
<content select=".myclass">
<content select=".myid">
<content select="input type=[text]">
<content select=":not(#test1)">
Shadow Insertion Points
You can create multipe shadow root for a host, but only the last one (referred as youngest) will be displayed. To include the previous shadow root, you need to include shadow tag in the displayed shadow root.
var host = document.getElementById('myshadowhost');
var root1 = host.createShadowRoot();
var root2 = host.createShadowRoot();
var root3 = host.createShadowRoot();
root1.innerHTML = '<div>Shadow DOM root1</div>';
root2.innerHTML = '<div>Shadow DOM root2</div> <shadow></shadow>'; // This will display older shadowRoot which in this case is root1
root3.innerHTML = '<div>Shadow DOM root3</div> <shadow></shadow>'; // This will display older shadowRoot which in this case is root2
You can use following methods in javascript to get hold of shadow roots
root.olderShadowRoot
host.shadowRoot will always return youngest shadowRoot
Events
Some of shadow dom events (like click) are re targeted as if they are coming from shodow host, where as some of the events (like change) are just killed at within shadow dom and is not re targeted.
No comments:
Post a Comment