【问题标题】:document.getElementById not behaving as expecteddocument.getElementById 的行为不符合预期
【发布时间】:2022-06-10 11:19:54
【问题描述】:

我正在尝试获取具有特定 ID 的 div 的内容。但是,如果 div 嵌套在诸如 <template> 之类的标签内,则无法找到它。我无法控制页面的 html 输出,所以我需要找到一种方法来找到这个元素,无论它嵌套在哪里。据我了解,document.getElementById 应该能够找到具有给定 ID 的元素,无论它位于何处。 javascript 代码始终位于正文末尾的脚本标记中。

它在下面按预期工作,嵌套在一个 div 中。

const str = document.getElementById("somethingsomething").innerText;
console.log(str);
<html>
<body>
<div>
  <div hidden="" id="somethingsomething">
    <b>dark side</b>
  </div>
</div>
</body>
</html>

这是我希望以相同方式工作但没有的示例。

const str = document.getElementById("somethingsomething").innerText;
console.log(str);
<html>
<body>
  <template>
  <div hidden="" id="somethingsomething">
    <b>dark side</b>
  </div>
</template>
</body>
</html>

【问题讨论】:

    标签: javascript dom


    【解决方案1】:

    A &lt;template&gt; 的孩子不会被渲染 - 他们并没有真正在页面上。作为MDN says

    将模板想象成一个内容片段,它被存储以供后续在文档中使用。虽然解析器在加载页面时确实会处理&lt;template&gt; 元素的内容,但它这样做只是为了确保这些内容有效;但是,不会呈现元素的内容。

    它在 DOM 中没有子元素。

    console.log(document.querySelector('template').children.length);
    <template>
      <p>foo</p>
    </template>

    因此,使用document.querySelector 或任何其他查找以文档为根的元素的方法都不会找到模板的任何后代。

    我认为你需要在这里做两件事:

    • 首先检查页面上是否存在该元素
    • 如果没有,它可能在模板中;遍历模板及其.content 以查看您要查找的内容是否在其中

    const getText = doc => doc.getElementById("somethingsomething")?.textContent;
    const getStr = () => {
      const textOnPage = getText(document);
      if (textOnPage !== undefined) return textOnPage;
      for (const template of document.querySelectorAll('template')) {
        const textInTemplate = getText(template.content);
        if (textInTemplate !== undefined) return textInTemplate;
      }
    };
    const str = getStr();
    console.log(str);
    <html>
    <body>
      <template>
      <div hidden="" id="somethingsomething">
        <b>dark side</b>
      </div>
    </template>
    </body>
    </html>

    【讨论】:

      【解决方案2】:

      &lt;template&gt; 元素包含标记,但内容不是 DOM 的一部分。页面加载后,可以通过 JavaScript 将内容添加一次或多次。

      【讨论】:

        【解决方案3】:

        &lt;template&gt; 标记使其中的所有内容隐藏起来,直到真正需要它时才被渲染。因此,您需要激活模板以获取其中定义的任何元素,否则它们将返回 null。

        您可以使用document.importNode(externalNode, deep) 来做到这一点。其中externalNode 引用模板元素本身,deep 表示是否要导入模板的整个子树。

        导入节点后,您需要将其附加到文档正文中,以便将其呈现到页面上,以便getElementById 可以看到它。

        您可以在以下链接中找到更深入的示例: document.getElementById doesn't work with <template> custom tag https://www.html5rocks.com/en/tutorials/webcomponents/template/#toc-using https://developer.mozilla.org/en-US/docs/Web/API/Document/importNode

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-01-27
          • 2022-01-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-09
          相关资源
          最近更新 更多