首页 文章

尝试在html导入中选择模板元素时获取null

提问于
浏览
1

在我的应用程序中,我从 A 执行html导入到文件 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>

这是googles的例子:

<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>

谢谢

1 回答

  • 1

    为什么会发生这种情况?

    导入包含 scripttemplate 的文件时要考虑的两个因素:

    • script 将在导入时执行,而标记和其他资源需要明确地添加到主页面

    • 正如article on imports所指出的(与谷歌文档相同,上面链接):

    导入链接并不意味着“#include这里的内容” . 它意味着“解析器,取消这个文档,以便我以后可以使用它” . 当脚本在导入时执行时,需要将样式表,标记和其他资源明确地添加到主页面 .

    • 执行导入中的脚本 in the context of the window that contains the imported document . 所以 window.document 指的是主页面文档,而不是模板文档 .

    这可以解释为什么您的脚本会发出警告 null .

    回答以下评论中的问题:Google的上述示例与相关示例有何不同?

    在Google的示例中,对 document.querySelector() 的调用位于自定义元素的构造函数中,该元素在实例化时被调用 . 因此,无论示例是否使用文件导入来定义自定义元素,在实例化元素之前都不会执行该代码 .

    如何使它工作:

    您可以创建对导入文档本身的引用,其中可以找到 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'));
    

相关问题