javascript - 嵌套元素(Web 组件)无法获取其模板

标签 javascript web-component shadow-dom html-imports html5-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>

应用容器.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>

工具栏.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 的模板。如何解决这个问题呢?

示例在 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 是本地定义的,因此您可以在其他文档中使用相同的名称。

关于javascript - 嵌套元素(Web 组件)无法获取其模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41408477/

相关文章:

javascript - 如何在没有 attachShadow 的情况下创建自定义元素?

javascript - Polymer 跨元素共享样式

javascript - 如何在 iOS6 上通过浏览器访问 IFA

javascript - 如何从特定语言的下拉列表中删除 "powered by google translate"并通过谷歌翻译器翻译网页

html - 如何在元素内容中访问模板的innerHTML

javascript - webcomponent内部可以使用vuejs吗?

javascript - 在 native DOM 中,有没有办法将两个节点组合起来形成一个范围以供查询?

javascript - 使用 Jasmine 和 Karma 进行 Angular Testing - 对于延迟加载的组件,路由器导出错误和组件创建测试失败

javascript - 为什么.splice总是删除最后一个元素?

javascript - Web 组件 : attributeChangedCallback not fired