vue3+electron 动态插入 iframe 如何自适应高度?

我在做一个需求,是需要从 electron 后台获取到 html 路径,之后动态创建 iframe 插入到编辑器
目前代码如下:

ipcRenderer.on("h5-iframe", (event, arg) => {
  let iframe = document.createElement('iframe');
  iframe.src = arg;
  iframe.width = '100%';
  iframe.src = arg
  console.log(1, iframe.contentDocument) // 1 null
  console.log(2, iframe.document) // 2 undefined

  iframe.addEventListener('load', (event) => {
    console.log(3, iframe.contentDocument)
    console.log(4, iframe.document)
  })
  iframe.onload = function () {
    console.log(5, iframe.contentDocument)
    console.log(6, iframe.document)
  }

  let div = document.createElement('div');
  div.appendChild(iframe);
  let iframeHtml = div.innerHTML;
  tinymce
    .get(tinymceId.value)
    .execCommand(
      "mceInsertContent",
      false,
      iframeHtml
    );
});

但得到的结果是如下,导致无法获取内容计算高度

console.log(1, iframe.contentDocument)null

console.log(2, iframe.document)undefined

frame.addEventListener('load', (event) => {})iframe.onload = function () {} 均无任何反馈

已知 arg 可以正确返回,
且页面可以正常插入显示,所以应该也不是跨域问题


请问如何解决?万分感谢!

阅读 499
avatarAI BotBETA

您好!

在 Electron 中,由于同源策略的限制,iframe 的 contentDocument 和 document 属性可能无法直接访问,尤其是在 iframe 加载的内容与主页面不同源时。

为了解决这个问题,您可以尝试以下方法:

  1. 监听 iframe 的 'load' 事件
* 正如您已经尝试过的,您可以通过监听 iframe 的 'load' 事件来获取其内容。但请注意,由于同源策略的限制,您可能无法直接访问 iframe 的 contentDocument 或 document 属性。
* 您可以尝试在 'load' 事件回调中,使用 postMessage API 向 iframe 发送消息,然后在 iframe 内部监听这个消息并作出响应。
  1. 使用 postMessage API
* 在主页面中,当 iframe 加载完成后,向其发送一个消息。
* 在 iframe 内部,监听这个消息,并作出相应的响应,例如调整高度。

示例代码:

主页面(Electron 主进程):

ipcRenderer.on("h5-iframe", (event, arg) => {
  let iframe = document.createElement('iframe');
  iframe.src = arg;
  iframe.width = '100%';

  iframe.addEventListener('load', (event) => {
    // 向 iframe 发送消息
    iframe.contentWindow.postMessage({ action: 'adjustHeight' }, '*');
  });

  let div = document.createElement('div');
  div.appendChild(iframe);
  let iframeHtml = div.innerHTML;
  tinymce
    .get(tinymceId.value)
    .execCommand(
      "mceInsertContent",
      false,
      iframeHtml
    );
});

iframe 页面:

window.addEventListener('message', (event) => {
  if (event.data.action === 'adjustHeight') {
    // 调整 iframe 高度
    document.body.style.height = '100vh'; // 或其他您希望的高度
  }
});

这样,即使由于同源策略的限制,您不能直接访问 iframe 的 contentDocument 或 document 属性,您仍然可以通过 postMessage API 与 iframe 进行通信,从而调整其高度。

请注意,上述代码仅为示例,您可能需要根据您的实际需求和场景进行调整。

希望这可以帮助到您!如果您还有其他问题,请随时提问。

1 个回答
ipcRenderer.on("h5-iframe", (event, arg) => {
  const iframe = document.createElement('iframe');
  iframe.src = arg;
  iframe.style.width = '100%';

  const editorContent = document.getElementById('editor-content'); 
  editorContent.appendChild(iframe);

  iframe.onload = function () {
    // 获取高度并调整
    const height = iframe.contentWindow.document.body.scrollHeight;
    iframe.style.height = `${height}px`;
  };
});

或者用 MutationObserver 监听 iframe 里面 DOM 变化:

function adjustIframeHeight(iframe) {
  const height = iframe.contentWindow.document.body.scrollHeight;
  iframe.style.height = `${height}px`;
}

ipcRenderer.on("h5-iframe", (event, arg) => {
  const iframe = document.createElement('iframe');
  iframe.src = arg;
  iframe.style.width = '100%';
  
  const editorContent = document.getElementById('editor-content'); // 确保这个元素存在
  editorContent.appendChild(iframe);

  iframe.onload = function () {
    adjustIframeHeight(iframe);
    const observer = new MutationObserver(() => adjustIframeHeight(iframe));
    observer.observe(iframe.contentDocument.body, { childList: true, subtree: true });
  };
});
推荐问题
宣传栏