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.
- Onko document.onload oikea tapa käsitellä, kun koodini suoritetaan tässä tapauksessa?
- 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.
