Javascript 无法查询使用Polyfill附加的ShadowRoot
在下面的示例中,我尝试创建一个菜单组件来试验组件层次结构 index.htmlJavascript 无法查询使用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
<!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谢谢。我已经包括了完整的代码