Прикрепленный ShadowRoot с использованием Polyfill не может запрашивать
В следующем примере я пытаюсь создать компонент меню для экспериментальной иерархии компонентов.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="robots" content="index, follow">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Sample Menu App</title>
<script src="js/webcomponents-lite.js"></script>
<!-- Components -->
<link rel="import" href="components/global/site-navigation.html">
</head>
<body>
<site-navigation></site-navigation>
</body>
</html>
/components/global/site-navigation.html
<link rel="import" href="nav-item.html">
<template>
<div class="nav">Header Goes here</div>
<ul class="nav">
<nav-item>Item 1</nav-item> <!-- This is a child component-->
</ul>
</template>
<script>
(function (currentDocument) {
customElements.define('site-navigation', class SiteNavigation extends HTMLElement {
constructor() {
super();
const shadowTemplate = currentDocument.querySelector('template').content.cloneNode(true);
this.DOM = this.attachShadow({ mode: 'open' });
this.DOM.appendChild(shadowTemplate);
console.log(this.DOM);
}
connectedCallback(){
this.Initialize();
}
Initialize(){
this.DOM.querySelector("div.nav").innerHTML = "Title"
}
});
})((document.currentScript || document._currentScript).ownerDocument);
</script>
/components/global/nav-item.html
<template>
<li class="nitem">
<a href="#">Elements</a>
</li>
</template>
<script>
(function(currentDocument) {
customElements.define('nav-item', class SiteNavigationItem extends HTMLElement {
constructor() {
super();
const shadowTemplate = currentDocument.querySelector('template').content.cloneNode(true);
this.DOM = this.attachShadow({ mode: 'open' });
this.DOM.appendChild(shadowTemplate);
}
connectedCallback(){
this.Initialize();
}
Initialize(){
let aTag = this.DOM.querySelector('a');
aTag.innerHTML = "Link 1"
}
});
})((document._currentScript||document.currentScript).ownerDocument);
</script>
Он отлично работает в Chrome. Я применил Polyfill, чтобы он работал в других браузерах. Однако метод Initialize завершается неудачно в FireFox с сообщением TypeError: this.DOM.querySelector(...) имеет значение null. При отладке установлено, что this.DOM = this.attachShadow({ mode: 'open' });
возвращает различные типы объектов в FF и Chrome, а в результате FF нет querySelector! Как я могу решить это?
ОБНОВЛЕНИЕ: родительский компонент (навигация по сайту) работает нормально, если удалена ссылка / ссылка на дочерний компонент (элемент nav).
1 ответ
Как вы заявили, кажется, что иерархия компонентов не поддерживается в полифиле HTML-импорта.
document.currentScript
тоже не работает. Polyfill скопирует <template>
в основном документе для 2 импортируемых документов.
Вот почему, когда вы запрашиваете querySelector ('template') в почтовом документе, это шаблон nav-item, который возвращается без div.nav
внутри.
Как трудоемкое, вы должны быть более конкретными, когда вы запрашиваете <template>
,
В site-navigtion.html:
<template id="site-navigation">
...
</template>
...
const shadowTemplate = currentDocument.querySelector('template#site-navigation').content.cloneNode(true);
Таким образом, вы получите правильный шаблон, даже в Firefox.
Замечания: document._currentScript
похоже, больше не работает с Polyfill v1.