JavaScript в лучших практиках Shadow DOM

У меня проблемы с настройкой JavaScript для правильной работы в Shadow DOM-элементах, которые я определяю. Учитывая следующий код:

<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 возвращает ноль. Если я заверну его в document.onload, он больше не выдаст ошибку, но нажатие на div тоже не вызовет предупреждение.

  1. Является ли document.onload правильным способом обработки моего кода в этом случае?
  2. Это правильный способ встраивать JavaScript для элементов теневого дома?

1 ответ

Решение

Shadow DOM tree

Вы должны привязать свой eventHandler внутри тега шаблона к #testElement:

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

Значение оригинального элемента / ShadowHost. Это потому, что события из ShadowElements выглядят так, как будто они созданы ShadowHost.

Javascript на самом деле не ограничен внутри ShadowDOM-Trees. Посмотрите, например, эту запись в блоге, которая охватывает именно эту тему:

Помните, когда я проводил все это время, объясняя, как Shadow DOM CSS был инкапсулирован и защищен от родительского документа и как это было здорово? Вы также можете подумать, что JavaScript работает так же, как я поначалу, но на самом деле это не так. [...] http://robdodson.me/blog/2013/09/02/shadow-dom-javascript/

В качестве объяснения перестановки событий в ShadowHost автор пишет:

Это потому, что события, приходящие от теневых узлов, должны быть перенаправлены, иначе они нарушат инкапсуляцию. Если цель события продолжала указывать на #shadow-text тогда любой мог бы покопаться в нашем Shadow DOM и начать все портить. http://robdodson.me/blog/2013/09/02/shadow-dom-javascript/

Я полагаю, что это хорошая идея, чтобы прочитать другие статьи этого блога, так как он, кажется, довольно хорошо освещает эту тему.

Пользовательские элементы

С пользовательскими элементами HTML у вас есть возможность использовать Javascript внутри пользовательских элементов HTML, см., Например, этот ответ по Stackru.

По сути, вы должны создать новый элемент HTML. Учебник доступен на html5rocks. Я думаю, что так, например, проект Polymer предоставляет свои пользовательские события.

Другие вопросы по тегам