嵌套元素(Web 组件)无法获取其模板
Nested element (web component) can't get its template
我使用带有两个自定义元素 (v1) 的 Web 组件制作了一个简单的示例,其中一个元素嵌套在另一个元素中。
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>
应用-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:
<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
中与在应用程序中相同-container.html 因此 querySelector('#app-toolbar')
找不到 ID 为 app-toolbar
的模板.如何解决这个问题呢?
示例在 Chrome 55(没有 polyfill)上测试。
document.currentScript
包含对当前解析和执行的脚本的引用。因此,当调用 constructor()
函数(从另一个脚本)时,它不再适用于您的目的。
相反,您应该将其值保存在脚本开头的变量中,并在构造函数中使用该变量:
<script>
var currentScript = document.currentScript
customElements.define( ... )
...
</script>
如果您有多个脚本,您应该使用不同的名称。
或者,您可以将临时值封装在闭包中:
(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
被分配给 owner
参数,在调用 constructor()
时该参数仍然正确定义。
owner
是本地定义的,因此您可以在其他文档中使用相同的名称。
我使用带有两个自定义元素 (v1) 的 Web 组件制作了一个简单的示例,其中一个元素嵌套在另一个元素中。 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>
应用-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:
<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
中与在应用程序中相同-container.html 因此 querySelector('#app-toolbar')
找不到 ID 为 app-toolbar
的模板.如何解决这个问题呢?
示例在 Chrome 55(没有 polyfill)上测试。
document.currentScript
包含对当前解析和执行的脚本的引用。因此,当调用 constructor()
函数(从另一个脚本)时,它不再适用于您的目的。
相反,您应该将其值保存在脚本开头的变量中,并在构造函数中使用该变量:
<script>
var currentScript = document.currentScript
customElements.define( ... )
...
</script>
如果您有多个脚本,您应该使用不同的名称。
或者,您可以将临时值封装在闭包中:
(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
被分配给 owner
参数,在调用 constructor()
时该参数仍然正确定义。
owner
是本地定义的,因此您可以在其他文档中使用相同的名称。