嵌套元素(Web组件)无法获取其模板 [英] Nested element (web component) can't get its template

查看:103
本文介绍了嵌套元素(Web组件)无法获取其模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用带有两个自定义元素(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆