Javascript 无法查询使用Polyfill附加的ShadowRoot

Javascript 无法查询使用Polyfill附加的ShadowRoot,javascript,web-component,shadow-dom,polyfills,html-imports,Javascript,Web Component,Shadow Dom,Polyfills,Html Imports,在下面的示例中,我尝试创建一个菜单组件来试验组件层次结构 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, initi

在下面的示例中,我尝试创建一个菜单组件来试验组件层次结构

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>
<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/site navigation.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>
<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>

标题在这里
    项目1
(功能(当前文档){ customElements.define('site-navigation',类SiteNavigation扩展HtmleElement{ 构造函数(){ 超级(); const shadowTemplate=currentDocument.querySelector('template').content.cloneNode(true); this.DOM=this.attachShadow({mode:'open'}); this.DOM.appendChild(shadowTemplate); log(this.DOM); } connectedCallback(){ 这是初始化(); } 初始化(){ this.DOM.querySelector(“div.nav”).innerHTML=“Title” } }); })((document.currentScript | | document._currentScript).ownerDocument);
/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>

  • (功能(当前文档){ customElements.define('nav-item',类SiteNavigationItem扩展HtmleElement{ 构造函数(){ 超级(); const shadowTemplate=currentDocument.querySelector('template').content.cloneNode(true); this.DOM=this.attachShadow({mode:'open'}); this.DOM.appendChild(shadowTemplate); } connectedCallback(){ 这是初始化(); } 初始化(){ 设aTag=this.DOM.querySelector('a'); aTag.innerHTML=“链接1” } }); })((document.| currentScript | document.currentScript).ownerDocument);
    它在铬合金中工作良好。我必须让它在其他浏览器中工作。但是,Initialize方法在FireFox中失败,消息为TypeError:this.DOM.querySelector(…)为null。调试时发现
    this.DOM=this.attachShadow({mode:'open'})在FF和Chrome中返回不同类型的对象,在FF结果中,没有querySelector!我如何处理这个问题

    FF结果

    铬结果

    更新:
    如果删除对子组件(导航项)的链接/引用,则父组件(站点导航)工作正常。

    如您所述,HTML导入polyfill中似乎不支持组件层次结构

    document.currentScript
    也不起作用。polyfill将为2个导入的文档复制主文档中的

    这就是为什么在邮件文档中查询querySelector(“模板”)时,返回的是nav项目的模板,其中没有
    div.nav

    作为一种解决方法,在查询
    时应该更加具体

    站点navigtion.html中:

    <template id="site-navigation">
    ...
    </template>
    ...
    const shadowTemplate = currentDocument.querySelector('template#site-navigation').content.cloneNode(true);
    
    
    ...
    ...
    const shadowTemplate=currentDocument.querySelector('template#site navigation').content.cloneNode(true);
    
    因此,即使在Firefox中,您也可以获得正确的模板


    注意:
    document.\u currentScript
    似乎不再适用于Polyfill v1。

    实际上,它适用于我(在构造函数中)使用PolyFillThank@Supersharp。建造商的生产线运转良好
    this.DOM=this.attachShadow({mode:'open'})。然而,当我试图设置div的innerHtml时,它失败了,出现了前面提到的错误。这正是失败的路线
    this.DOM.querySelector(“div.nav”).innerHTML=“Title”
    它适合我。也许你应该提供更多的代码我已经猜出了罪魁祸首,但我不明白为什么会发生这种情况。对子组件的引用会导致问题。我已经删除了第
    行以及它的引用,这使得组件可以正常工作。polyfill中不支持组件层次结构吗?@Supersharp谢谢。我已经包括了完整的代码