动态创建的 iframe 给定 HTML 后, contentDocument = null 问题

问题描述

在使用 iframe 解析一个 HTML 时, 通过 document.createElement('iframe') 创建 iframe, 并设置 srcdoc 后, 发现 contentDocument = null

复现代码如下:

  const oIframe = document.createElement('iframe')
  oIframe.srcdoc = `<!doctype html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport"
            content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
    </head>
    <body>
      <p>我是段落</p>
    </body>
  </html>`

  oIframe.style.display = 'none'
  const oP = oIframe.contentDocument.querySelector('p')
  console.log(oP.innerText)

上面代码会报错:

VM4928:17 Uncaught TypeError: Cannot read properties of null (reading 'querySelector')
    at <anonymous>:17:38

意思是: iframe 的 contentDocument 为 null。

这是因为在 在 javascript 中创建的 iframesrcdoc 不会触发 HTML 解析器,直到元素被插入到文档中。 然后更新 HTML,调用HTML解析器并按预期处理属性。

解决方法

将创建好的 iframe 插入到 文档中, 并在加载成功后, 再进行文档操作。

  const oIframe = document.createElement('iframe')
  oIframe.srcdoc = `<!doctype html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport"
            content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
    </head>
    <body>
      <p>我是段落</p>
    </body>
  </html>`

  oIframe.style.display = 'none'

  document.body.appendChild(oIframe)
  oIframe.onload = () => {
    const oP = oIframe.contentDocument.querySelector('p')
    console.log(oP.innerText)

    // 使用完毕后移除
    document.body.removeChild(oIframe)
  }

可以正常输出 我是段落

参考

Creating an iframe with given HTML dynamically

posted @ 2022-05-25 16:55  暗恋桃埖源  阅读(2924)  评论(0编辑  收藏  举报