嵌套元素(Web组件)无法获取其模板 [英] Nested element (web component) can't get its template
问题描述
我使用带有两个自定义元素(v1)的Web组件做了一个简单的例子,其中一个嵌套在另一个元素中。
index.html:
I made a simple example using Web Components with two custom elements (v1) where one is nested in another. index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Example</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="import" href="app-container.html">
</head>
<body>
<app-container></app-container>
</body>
</html>
app-container.html:
app-container.html:
<link rel="import" href="toolbar.html">
<template id="app-container">
<app-toolbar></app-toolbar>
</template>
<script>
customElements.define('app-container', class extends HTMLElement {
constructor() {
super();
let shadowRoot = this.attachShadow({ mode: 'open' });
const content = document.currentScript.ownerDocument.querySelector('#app-container').content;
shadowRoot.appendChild(content.cloneNode(true));
}
});
</script>
toolbar.html:
toolbar.html:
<template id="app-toolbar">
<p>Ok!</p>
</template>
<script>
customElements.define('app-toolbar', class extends HTMLElement {
constructor() {
super();
let shadowRoot = this.attachShadow({ mode: 'open' });
const content = document.currentScript.ownerDocument.querySelector('#app-toolbar').content;
shadowRoot.appendChild(content.cloneNode(true));
}
});
</script>
但在toolbar.html document.currentScript
与app-container.html中的相同,因此 querySelector('#app-toolbar')
找不到ID app的模板-toolbar
。如何解决这个问题呢?
But in the toolbar.html document.currentScript
is the same as in the app-container.html and hence querySelector('#app-toolbar')
can't find template with id app-toolbar
. How to solve this problem?
在Chrome 55上测试的示例(不含polyfill)。
Example tested on Chrome 55 (without polyfill).
推荐答案
document.currentScript
包含对当前正在解析和执行的脚本的引用。因此,当调用构造函数()
函数(来自另一个脚本)时,它不再适用于您的目的。
document.currentScript
contains a reference to the script that is currently parsed and executed. Therefore it is not valid anymore for your purpose when the constructor()
function is called (from another script).
相反,你应该在脚本开头的变量中保存它的值,并在构造函数中使用这个变量:
Instead you shoud save its value in a variable at the beginning of the script, and use this variable in the constructor:
<script>
var currentScript = document.currentScript
customElements.define( ... )
...
</script>
如果您有多个脚本,则应使用不同的名称。
If you have multiple scripts, you should use distinct names.
或者,您可以将临时值封装在闭包中:
Alternately, you can encapsulate the ephemeral value in a closure:
(function(owner) {
customElements.define('app-container', class extends HTMLElement {
constructor() {
super();
let shadowRoot = this.attachShadow({ mode: 'open' });
const content = owner.querySelector('#app-container').content;
shadowRoot.appendChild(content.cloneNode(true));
}
});
})(document.currentScript.ownerDocument);
这里的值 document.currentScript.ownerDocument
分配给所有者
参数,该参数在调用 constructor()
时仍然正确定义。
Here the value document.currentScript.ownerDocument
is assigned to the owner
argument which is still defined correctly when constructor()
is called.
所有者
是本地定义的,因此您可以在其他文档中使用相同的名称。
owner
is locally defined so you can use the same name in the other document.
这篇关于嵌套元素(Web组件)无法获取其模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!