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 тоже не вызовет предупреждение.
- Является ли document.onload правильным способом обработки моего кода в этом случае?
- Это правильный способ встраивать 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 предоставляет свои пользовательские события.