Прикрепленный 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! Как я могу решить это?

ФФ Результат

Результат Firefox

Chrome Result

Chrome Result

ОБНОВЛЕНИЕ: родительский компонент (навигация по сайту) работает нормально, если удалена ссылка / ссылка на дочерний компонент (элемент 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.

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