iframe 问题: <script src="..."> 根本没有加载

MiB*_*MiB 5 javascript iframe

我在使用中遇到一些问题iframe。我一次会问一个问题。我正在LaTeX.js 游乐场上工作,想要添加一些 JavaScript 来处理\marginpars,但无论我做什么,Chrome 和 Firefox 都不会尝试加载脚本。如果在任何框架之外使用完全相同的代码,它就会起作用。

我尝试了绝对路径和相对路径,并且尝试了filehttphttps协议。总是相同的结果。

这是相关代码:

<iframe id="preview" sandbox="allow-same-origin allow-scripts">
  <html>
    <head>
      <title>LaTeX.js Show&shy;case</title>
      <meta charset="UTF-8">
      <link type="text/css" rel="stylesheet" href="css/katex.css">
      <link type="text/css" rel="stylesheet" href="css/article.css">
      <link type="text/css" rel="stylesheet" href="css/error.css">

      <script src="https://latex.js.org/js/base.js"></script>
    </head>
    ...
Run Code Online (Sandbox Code Playgroud)

问题是base.js。开发人员工具在控制台中没有显示任何错误,在源选项卡中没有显示任何条目,在网络选项卡中也没有显示任何条目。

更新:正如我在评论中所说,上面的代码是使用 JavaScript 修改 DOM 的结果;但是,设置iframe.contentWindow.document.documentElement似乎不会触发加载脚本<head>,只有答案中的选项 2 对我有用。

Ste*_*eve 6

选项 1:使用 DOM

对我来说iframe.contentWindow.replaceChild(newDocumentElement, iframe.contentWindow.documentElement)不起作用(replaceChild不是方法,并且iframe.contentWindow.documentElement.parentNode为空)。我成功更换了 iframe 的头部和主体:

var iframe = document.getElementById('preview');
var iframeDocument = iframe.contentDocument;
var head = document.createElement('head');
var body = document.createElement('body');
var library = document.createElement('script');

//library.src = 'https://latex.js.org/js/base.js';
library.src = 'https://d3js.org/d3.v4.min.js';
head.appendChild(library);
body.appendChild(document.createTextNode('Hello, World!'));
iframeDocument.head.parentNode.replaceChild(head, iframeDocument.head);
iframeDocument.body.parentNode.replaceChild(body, iframeDocument.body);
Run Code Online (Sandbox Code Playgroud)

这是一个小提琴: https: //jsfiddle.net/zkb91faf/

您可以d3.v4.min.js通过导航到调试器中的 iframe(有关 Chrome 的信息,请参见此处有关 Firefox 的信息请参见此处)并d3在控制台中键入内容来验证是否已正确加载。

选项 2:使用src/srcdoc

如果我不提的话,那就是我的失职了iframe.srcdoc。看起来您只是使用静态 HTML,所以它可能是合适的。

你只需通过以下方式设置它:

iframe.srcdoc = newDocumentElement.outerHTML;

iframe.src或者,如果您想支持旧版浏览器,您可以通过数据 URI进行设置:

iframe.src = 'data:text;base64,' + btoa(newDocumentElement.outerHTML);
Run Code Online (Sandbox Code Playgroud)

如果您需要 unicode 支持,请参阅https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding

注意使用相对 URL:

使用相对 URL 时您可能会遇到问题,就像 中的那样<link type="text/css" rel="stylesheet" href="css/article.css">,因为您的 iframe 没有正确的 URI。您可能需要使用绝对 URL。

更新:加载文档后添加脚本标签:

看起来罪魁祸首就在base.js根据DOMContentLoaded事件附加并运行代码的地方。DOM 已经加载,因此该事件不会触发。您可以做的是检查窗口是否已加载,然后运行初始化代码(如果是)。通过/sf/answers/662059751/

if (document.readyState === "complete" || document.readyState === "loaded") {
     completed();
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您可能需要在头部之前替换主体,以防万一completed()对 DOM 进行任何直接操作。