web-dev-qa-db-fra.com

Comment interroger des éléments dans le DOM fantôme de l'extérieur dans Dart?

Comment puis-je sélectionner des nœuds dans le DOM fantôme? Prenons l'exemple suivant:

structure du DOM "non masqué"

<app-element>
  #shadow-root
    <h2></h2>
    <content>
      #outside shadow
      <h2></h2>
    </content>
    <ui-button>
      #shadow-root
        <h2></h2>
  </ui-button>
</app-element>

index.html

<body>
<app-element>
  <!-- OK: querySelect('app-element').querySelect('h2') -->
  <!-- OK: querySelect('app-element h2') -->
  <!-- There is no problem to select it -->
  <h2>app-element > content > h2</h2>
</app-element>
</body>

templates.html

<polymer-element name="ui-button" noscript>
  <template>
    <!-- FAIL: querySelect('app-element::shadow ui-button::shadow h2') -->
    <h2>app-element > ui-button > h2</h2>
  </template>
</polymer-element>

<polymer-element name="app-element" noscript>
  <template>
    <!-- FAIL: querySelect('app-element::shadow').querySelect('h2') -->
    <!-- FAIL: querySelect('app-element::shadow h2') -->
    <!-- FAIL: querySelect('app-element').shadowRoot.querySelect('h2') -->
    <h2>app-element > h2</h2>
    <content></content>
    <ui-button></ui-button>
  </template>
</polymer-element>

Dans des commentaires comme "OK: querySelect ()", je montre les sélecteurs que j'ai essayé d'exécuter depuis l'extérieur de tout DOM ombré.

J'ai déjà lu l'article suivant: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201/?redirect_from_locale=r et basé sur le fait qu'il a été dit dans l'article, requête comme: document.querySelector('app-element::shadow h2'); dans JS devrait fonctionner comme prévu. Cependant, à Dart, cela ne fonctionne pas.

Qu'est-ce que j'ai tort?

17

Update2 (à partir des commentaires)

Si vous utilisez un main personnalisé, assurez-vous que Polymer est correctement initialisé avant d'essayer d'interagir avec vos éléments Polymer (voir comment implémenter un fonction principale dans polymer apps pour plus de détails).

Je suggère généralement d'éviter un main personnalisé et de créer un app-element (Ou le nom que vous préférez) et de mettre votre code d'initialisation dans attached (assurez-vous d'appeler super.attached();) ou dans ready() (n'a pas besoin du super appel).

Original

Il semble que dans ce cas ce n'est pas dans le DOM fantôme mais un enfant.

Cela devrait fonctionner:

querySelector('h2');

Ce n'est que dans le DOM fantôme quand il se trouve dans vos éléments <template>...</template> Pas lorsque vous l'enveloppez dans la balise de votre élément personnalisé.

<polymer-element name="some-element">
  <template>
    <!-- this becomes the shadow DOM -->
    <content>
     <!-- 
       what gets captureD by the content element becomes a child or some-element
       -->
     </content>
  </template>
</polymer-element>
<body>
  <some-element>
    <!-- these elements here are captured by the 
         content tag and become children of some-element -->
    <div>some text</div>
  </some-element>
</body>

Mise à jour

Si vous souhaitez rechercher

à l'intérieur du DOM ombre de l'élément courant

shadowRoot.querySelect('h2');

à l'intérieur du DOM ombre d'un élément à l'intérieur du DOM ombre

shadowRoot.querySelector('* /deep/ h2');
shadowRoot.querySelector('ui-button::shadow h2');

de l'extérieur de l'élément courant

import 'Dart:html' as dom;
...
dom.querySelector('* /deep/ h2');
// or (only in the shadow DOM of <app-element>)
dom.querySelector('app-element::shadow h2');
dom.querySelector('app-element::shadow ui-button::shadow h2');
// or (arbitrary depth)
dom.querySelector('app-element /deep/ h2');
12
Günter Zöchbauer

Pseudo sélecteur ::shadow et combinateur /deep/ ne fonctionne pas sur Firefox.

Utilisation .shadowRoot

var shadowroot = app-element.shadowRoot;
shadowroot.querySelector('h2');
19
Aniruddha

Fonction d'assistance Vanilla only utilisant la méthode de réduction

function queryShadow([firstShadowSelector, ...restOfTheShadowSelectors], itemSelector) {
    const reduceFunction = (currShadow, nextShadowSelector) => currShadow.shadowRoot.querySelector(nextShadowSelector);    
    const firstShadow = document.querySelector(firstShadowSelector);
    const lastShadow = restOfTheShadowSelectors.reduce(reduceFunction,firstShadow);
    return lastShadow && lastShadow.querySelector(itemSelector);
}

et l'utiliser comme ça

const shadowSelectorsArr = ['vt-virustotal-app','file-view', '#report', 'vt-ui-file-card', 'vt-ui-generic-card'];
const foundDomElem = queryShadow(shadowSelectorsArr, '.file-id');
console.log(foundDomElem && foundDomElem.innerText);
0
yoni12ab