1

在我的应用程序中,我将 html 导入A到具有此文件的文件B中。但它警告null。如果我B直接在浏览器中打开,它会提醒模板 HTML dom 元素。这怎么会发生,同样的代码几乎来自谷歌自己的网络组件文档https://developers.google.com/web/fundamentals/architecture/building-components/customelements

<template id="x-foo-from-template">

</template>

<script>
    alert(document.querySelector('template'));
</script>

这是谷歌的例子:

<template id="x-foo-from-template">
  <style>
    p { color: orange; }
  </style>
  <p>I'm in Shadow DOM. My markup was stamped from a &lt;template&gt;.</p>
</template>

<script>
  customElements.define('x-foo-from-template', class extends HTMLElement {
    constructor() {
      super(); // always call super() first in the ctor.
      let shadowRoot = this.attachShadow({mode: 'open'});
      const t = document.querySelector('#x-foo-from-template');
      const instance = t.content.cloneNode(true);
      shadowRoot.appendChild(instance);
    }
    ...
  });
</script>

谢谢

4

1 回答 1

1

为什么会这样?

script导入包含 a和 a的文件时要考虑的两个因素template

  1. script在导入时执行,而标记和其他资源需要显式添加到主页
    • 正如这篇关于导入的文章所指出的(由 Eric Bidelman,与相关链接的 Google 文档的作者相同):

导入链接并不意味着“ #include the content here ”。它的意思是“解析器,去获取这个文档,以便我以后可以使用它”。虽然脚本在导入时执行,但样式表、标记和其他资源需要显式添加到主页。

  1. 导入中的脚本在包含导入文档的窗口上下文中执行。所以window.document指的是主页文档,而不是模板文档。

这应该可以解释为什么您的脚本会发出警报null。因为脚本是立即执行的,而模板还没有被添加到主页。

如何获得想要的结果:

template您可以在可以找到的地方创建对导入文档本身的引用。

// importDoc references this import's document
var importDoc = document.currentScript.ownerDocument;

alert(importDoc.querySelector('template'));

或者,您可以在将模板插入文档后查询主文档:

var import = document.querySelector('link[rel="import"]').import;
var template = import.querySelector('template');

// Append template to main document
document.head.appendChild(template);

// Now you can query the main the document
alert(document.querySelector('template'));

Google 的示例与相关示例有何不同?

针对以下评论中的问题:

在 Google 的示例中,调用document.querySelector()是在自定义元素的构造函数中找到的。实例化元素时调用构造函数。因此,运行此代码时,该元素已存在于主页中。

于 2017-08-17T04:50:45.017 回答