最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

html - JavaScript within Shadow DOM best practices - Stack Overflow

programmeradmin2浏览0评论

I'm having trouble getting JavaScript to run properly within Shadow DOM elements I'm defining. Given the following code:

<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 is returning null. If I wrap it in document.onload it no longer throws the error, but clicking the div doesn't launch the alert, either.

  1. Is document.onload the proper way to handle when my code runs in this case?
  2. Is this the proper way to embed javascript for shadow dom elements?

I'm having trouble getting JavaScript to run properly within Shadow DOM elements I'm defining. Given the following code:

<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 is returning null. If I wrap it in document.onload it no longer throws the error, but clicking the div doesn't launch the alert, either.

  1. Is document.onload the proper way to handle when my code runs in this case?
  2. Is this the proper way to embed javascript for shadow dom elements?
Share Improve this question edited Jul 31, 2014 at 7:44 doniyor 37.9k61 gold badges181 silver badges270 bronze badges asked Jul 30, 2014 at 23:00 anderspitmananderspitman 10.6k11 gold badges44 silver badges69 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 6

Shadow DOM tree

You must bind your eventHandler inside the template tag to #testElement:

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

Meaning to the original element / ShadowHost. That is, because Events from ShadowElements appear as if they originated by the ShadowHost.

Javascript is actually not scoped inside of ShadowDOM-Trees. See for example this blog entry, which covers exactly that topic:

Remember when I spent all of that time explaining how Shadow DOM CSS was encapsulated and protected from the parent document and how awesome that all was? You might also think that JavaScript works the same way—I did at first—but that’s actually not the case. [...] https://robdodson.me/shadow-dom-javascript/

As an explanation for rearranging the events to the ShadowHost the author writes:

This is because events ing from shadow nodes have to be retargeted otherwise they would break encapsulation. If the event target continued to point at #shadow-text then anyone could dig around inside of our Shadow DOM and start messing things up. https://robdodson.me/shadow-dom-javascript/

I suppose it is a good idea to read other articles of this blog too, as it seems to cover the topic pretty well.

Custom elements

With custom HTML elements you have the ability to use Javascript inside of custom HTML elements, see for example this answer on Stackoverflow.

Basically you must create a plete new HTML element. A tutorial is available at html5rocks. I think this is how for example the Polymer project provides its custom events.

发布评论

评论列表(0)

  1. 暂无评论