Est-il possible d'accéder aux éléments Shadow DOM via le document parent?

Cette question est plus destinée aux éléments d'ombre DOM créés par l'utilisateur, mais pour l'accessibilité, j'utiliserai le type de saisie de la date pour cette question:

Dis, par exemple, j'ai une entrée de date sur ma page. Avec quelques bits édités, le balayage DOM de l'ombre pour cela (en utilisant Chrome) ressemble à quelque chose comme:

 <input type="date"> #document-fragment <div pseudo="-webkit-datetime-edit"> <div pseudo="-webkit-datetime-edit-fields-wrapper"> <span role="spinbutton">dd</span> <div pseudo="-webkit-datetime-edit-text">/</div> <span role="spinbutton">mm</span> <div pseudo="-webkit-datetime-edit-text">/</div> <span role="spinbutton">yyyy</span> </div> </div> <div></div> <div pseudo="-webkit-calendar-picker-indicator"></div> 

Les méthodes et les propriétés associées à l'entrée de la date ne semblent pas faire référence à l'ombre DOM du tout ( JSFiddle ), alors je me demandais comment (si du tout) ces éléments d'ombre DOM sont-ils accessibles?

int32_t est juste dans ce DOM d'ombre, par définition, est un moyen de remplir un nœud avec DOM que vous souhaitez cacher à partir de sources externes ( Encapsulation ). Le fait est que vous, comme l'auteur du composant, choisissez exactement quelles parties seront exposées à l'extérieur de CSS ou JavaScript et qui ne le feront pas.

Malheureusement, vous ne pouvez pas créer une interface JavaScript publique à votre Shadow DOM sans utiliser une autre spécification de saignement appelée Custom Elements . Si vous choisissez de le faire, il est aussi simple que d'ajouter des méthodes publiques personnalisées au prototype de votre élément. À partir de cela, vous pouvez accéder aux éléments internes de votre DOM d'ombre (voir le troisième exemple ici ).

Toutefois, vous pouvez exposer des crochets à CSS pour accéder à l'intérieur de votre DOM d'ombre sans utiliser d'éléments personnalisés. Il existe deux façons de le faire:

  1. Pseudo-éléments
  2. Variables CSS

Pseudo-éléments

Chrome et Firefox exposent certaines parties de leur Shadow DOM à CSS à travers des pseudo-éléments spéciaux. Voici votre exemple de saisie de la date avec l'ajout d'une règle CSS qui s'applique uniquement à la partie numérique du champ de la date en utilisant le pseudo-élément -webkit-datetime-edit par Chrome-fourni -webkit-datetime-edit .

Voici une liste partielle des pseudo-éléments WebKit disponibles. Vous pouvez également activer l'option Show Shadow DOM dans DevTools et rechercher les attributs appelés pseudo .

Les auteurs de composants peuvent également créer leurs propres pseudo-éléments pour exposer des parties de leur Ombre DOM (voir le 2ème exemple ici ).

Variables CSS

Une façon encore meilleure est d'utiliser les variables CSS, que vous pouvez activer avec Enable experimental WebKit features dans les about:flags en Chrome. Ensuite, vérifiez cette violon qui utilise les variables CSS pour communiquer avec le Ombre DOM de la couleur qu'il devrait utiliser pour son «thème».

Maintenant (2016), vous pouvez accéder aux éléments Open DOM créés par l'utilisateur ouverts (mais pas d'ombre créée par l'utilisateur DOM!) À l'aide de la méthode querySelector sur la racine DOM Shadow:

 <body> <div id="container"></div> <script> //Shadow Root var root = container.createShadowRoot() //new syntax: var root = container.attachShadow( { mode: "open" } ) //Inside element var span = document.createElement( "span" ) span.textContent = "i'm inside the Shadow DOM" span.id = "inside" root.appendChild( span ) //Access inside element console.log( container.shadowRoot.querySelector( "#inside" ) ) </script> </body> 
 //Shadow Root var root = container.createShadowRoot() //Inside element var span = document.createElement( "span" ) span.textContent = "i'm inside the Shadow DOM" span.id = "inside" root.appendChild( span ) //Access inside element function get() { alert( container.shadowRoot.querySelector( "#inside" ).id ) } 
 <!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8" /> </head> <body> <div id="container"></div> <button onclick="get()">Get</button> <script> </script> </body> </html> 

Vous ne pouvez pas accéder au contenu de Shadow DOM à partir de scripts en dehors du Shadow DOM. L'encapsulation est l'objet de Shadow DOM.