【问题标题】:How do I run code inside an iFrame that was NOT defined in the iframe?如何在 iframe 中运行未在 iframe 中定义的代码?
【发布时间】:2016-02-24 01:37:03
【问题描述】:

我需要像在页面上的 iframe 中运行代码一样运行代码,这意味着当我在该代码中使用 window 时,它应该使用 iframe 的窗口对象。它不是我创建的 iframe,所以我的函数没有在其中定义。

var myfunction = function () { // defined in parent, not in the iframe
  console.log(window); // window here should be the iframe's window object, not the parent/
  window.document.body.appendChild("Appending to iframe body");
}

// Need to somehow run this function inside the iframe
myfunction(); // as if I did this inside the iframe

我需要这个确切的代码在 iframe 中运行,我知道我可以自己修复这个问题

frames["FrameName"].document.body.appendChild("Appending to iframe body");

但这并不能解决我的问题。

这是因为我没有自己编写代码,有一个名为 Opentip 的模块用于创建工具提示。我需要在 iframe 内的元素上设置工具提示;但是,Opentip 在其代码中使用 window 对象来正确创建工具提示。

所以我需要运行

Opentip(myelement, data);

好像我在 iframe 中运行它,但没有在 iframe 中定义它。

所以Opentip函数需要使用iframe窗口,而不是父窗口。

【问题讨论】:

  • 最简单的方法是将 Opentip 脚本注入到 iframe 的文档中,方法是在其 dom 中添加一个外部脚本标签。然后你可以调用frames["FrameName"].Opentip(frames["FrameName"].document.body, data)注入脚本:frames["FrameName"].document.body.appendChild(frames["FrameName"].document.createElement("script")).src="http://example.com/script.js";
  • 框架的内容是否与您的网站来自同一来源(域名)?
  • 我在 chrome 扩展 @MattiVirkkunen 的 content_script 中运行所有 javascript
  • @dandavis 我会试试你提到的
  • @MattiVirkkunen 是的(我错了,我误解了你所说的)

标签: javascript jquery html css iframe


【解决方案1】:

提供的代码当然未经测试。这是假设的答案:

  • OP情况是满足same origin policy的要求。
  • OP 无法直接编辑子页面。
  • OP 不能使用 Ajax。

资源

片段

//A//Ref to iframe
var iFrm = document.getElementById('iFrm')

//B//Listen for load event 
iFrm.addEventListener('load', function(e) {
  
  //C//Ref to iframe Window
  var iWin = iFrm.contentWindow;
  
  //D//Ref to iframe Document 
  var iDoc = iFrm.contentDocument? iFrm.contentDocument:iFrm.contentWindow.document;
  
  //E//Ref element targeted by Opentip--replace {{>SEL<}} with appropriate selector
  var iTgt = document.querySelector({{>SEL<}});
  
  //F//Create, configure, deploy, and inject <script> tag to iframe <head>
  var iNode = document.createElement(`script`);
  iNode.src = "https://cdn.jsdelivr.net/opentip/2.4.6/opentip-native.min.js";
  iDoc.head.appendChild(iNode); 
  
  //G//Call Opentip from iframe Window, and hopefully in iframe's context
  iFrm.contentWindow.Opentip = function(iTgt, data);
}
  
/* Notes */
/*//F//Alternative to target iframe <head>:
window.frames["iFrm"].document.getElementsByTagName("head")[0];*/
                      
   /*//If not successful in accuirring iframe, try replacing all
 "document." with "contentWindow", "contentDocument", or "contentWindow.document"*/
<iframe id="iFrm" name="iFrm" src="/"></iframe>

<!--Optionally you can add an onload event to the iframe itself

<iframe id="iFrm" name="iFrm" src="/"></iframe>

-->

【讨论】:

  • 我遇到了一些奇怪的事情。一旦我调用iFrm.contentWindow.Opentip(在加载事件监听器中)它说iFrm.contentWindow.Opentip仍然未定义,但在它给我那个错误之后,我在浏览器控制台中再次手动检查它存在(我可以运行它).. . 我不确定,但我认为事件侦听器可能正在拍摄存储在iFrm.contentWindo.Opentip 中的数据的快照,其中未定义而不是访问新定义的函数。有什么想法吗?
  • 如果你得到奇怪的结果,很可能是因为 Opentip 绑定到了窗口。调用函数时,必须建立正确的上下文。不幸的是,由于您是从子页面调用的,因此考虑到 Windows 是全局的,它并没有被简单化和干燥,实际的窗口可能被认为是父窗口而不是属于子页面的窗口。为了获得对孩子窗口的正确引用,我认为调用需要来自父母。试试ifrm.contentWindow.document.Opentipparent.contentDocument.document.Opentip
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-14
  • 2015-03-31
  • 1970-01-01
相关资源
最近更新 更多