html - JavaScript Shadow DOMissa parhaat käytännöt


Minulla on vaikeuksia saada JavaScript toimimaan oikein määrittämieni Shadow DOM -elementtien sisällä. Kun otetaan huomioon seuraava koodi:

<template id='testTemplate'>
 <div id='test'>Click to say hi</div>
 <script>
  var elem = document.querySelector('#test');
  elem.addEventListener('click', function(e) {
     alert("Hi there");
  });
</script>
</template>

<div id="testElement">Host text</div>

<script>
  var shadow = document.querySelector('#testElement').createShadowRoot();
  var template = document.querySelector('#testTemplate');
  shadow.appendChild(template.content.cloneNode(true));
</script>

document.querySelector palauttaa null-arvon. Jos käärin sen document.onloadiin, se ei enää heitä virhettä, mutta diviä klikkaamalla alert ei myöskään käynnisty.

  1. Onko document.onload oikea tapa käsitellä, kun koodini suoritetaan tässä tapauksessa?
  2. Onko tämä oikea tapa upottaa JavaScript varjodomin elementteihin?

Vastaus #1

Varjomaisen DOM-puun

Sinun on sitouduttava tapahtumankäsittelijääsi template-tunnisteen sisällä kohteeseen #testElement:

var elem = document.querySelector('#testElement');

Merkitys alkuperäiselle elementille/ShadowHostille. Eli koska tapahtumat ShadowElementsistä näyttävät tulevan ikään kuin ne olisivat peräisin ShadowHostilta.

Javascript ei itse asiassa ole suljettu ShadowDOM-puiden sisälle. Katso esimerkiksi tämä blogikirjoitus, joka käsittelee juuri tätä aihetta:

Muistatko, kun käytin kaiken sen ajan selittäen, miten Shadow DOM -CSS on kapseloitu ja suojattu vanhemmalta dokumentilta ja kuinka mahtavaa se kaikki oli? Saatat myös ajatella, että JavaScript toimii samalla tavalla—minä ajattelin aluksi niin—mutta todellisuudessa asia ei ole näin. [...] https://robdodson.me/shadow-dom-javascript/

Selityksenä tapahtumien uudelleenjärjestelyyn ShadowHostille kirjoittaja kirjoittaa:

Tämä johtuu siitä, että varjonodeista tulevat tapahtumat on ohjattava uudelleen, muuten ne rikkoisivat kapseloinnin. Jos tapahtuman kohde jatkaisi osoittamista #shadow-text-elementtiin, kuka tahansa voisi kaivaa meidän Shadow DOM -rakenteemme sisälle ja alkaa sotkemaan asioita. https://robdodson.me/shadow-dom-javascript/

Oletan, että on hyvä idea lukea myös tämän blogin muita artikkeleita, sillä näyttää siltä, että se käsittelee aihetta melko hyvin.

Mukautetut elementit

Mukautettujen HTML-elementtien avulla sinulla on mahdollisuus käyttää Javascriptiä mukautettujen HTML-elementtien sisällä, katso esimerkiksi tämä vastaus Stackoverflow'ssa.

Periaatteessa sinun täytyy luoda täysin uusi HTML-elementti. Opas on saatavilla html5rocks-sivustolla. Luulen, että tämä on esimerkiksi tapa, jolla Polymer-projekti tarjoaa omat mukautetut tapahtumansa.