有没有办法找出哪个iframe调用父的JavaScript函数

时间:2012-11-27 10:10:42

标签: javascript html5 iframe

这是一个例子

parent.html

<script>
function printWhoCalledMe() {
  console.log(???);  // what goes here that will identify the caller?
}
<iframe src="iframe1.html"></iframe>
<iframe src="iframe2.html"></iframe>

iframe1.html

<script>
window.parent.printWhoCalledMe();
</script>

iframe2.html

<script>
window.parent.printWhoCalledMe();
</script>

更大的问题是I have a test harness that runs a bunch of tests, one at a time, in an iframe。每个测试都会调用window.parent.reportOnTest(success)

我正在考虑通过在多个iframe中运行测试来并行化测试,但我必须完成每个测试,目前进行1000次测试,并将他们的调用从window.parent.reportOnTest(success)更改为{{1}或类似的东西。

我想知道是否有办法在不修改测试的情况下,找出哪个测试调用了父测试。

注意:我试过

window.parent.reportOnTest(success, window.location.href)

但那会打印父母的href。

4 个答案:

答案 0 :(得分:0)

我担心你可能不得不使用这样的字符串值..

function printWhoCalledMe(callerPage) {
  console.log(callerPage);  // what goes here that will identify the caller?
}

并且您可以使用类似的参数从您的子框架调用此函数..

iframe1.html

<script>
window.parent.printWhoCalledMe("iframe1");
</script>

iframe2.html

<script>
window.parent.printWhoCalledMe("iframe2");
</script>

答案 1 :(得分:0)

如果使用apply调用父函数,则可以将上下文更改为框架window

window.parent.printWhoCalledMe.apply(this);

function printWhoCalledMe() {
  console.log(this); // this now refers to the frame window
}

答案 2 :(得分:0)

如此hacky,但你可以使用这样的东西:

  1. 使用caller获取对调用所需函数的函数的引用。
  2. 继续使用Object.getPrototypeOf,直至到达该领域的Object.prototype
  3. 迭代所有框架窗口,并比较Object.prototype
  4. 找到匹配项后,请使用frameElement获取iframe。
  5. 这需要sameorigin,没有沙盒和草率模式。例如:

    window.func = function func() {
      var proto, nextProto = func.caller;
      while (nextProto) {
        proto = nextProto;
        nextProto = Object.getPrototypeOf(proto);
      }
      var win = [].find.call(window.frames, function(win) {
        try {
          return win.Object.prototype === proto;
        } catch(err) {
          return false;
        }
      });
      if (win) {
        var iframe = win.frameElement;
        console.log("function called from frame " + iframe.name);
      }
    };
    var iframe = document.createElement('iframe');
    iframe.name = "myframe";
    document.body.appendChild(iframe);
    var doc = iframe.contentDocument;
    var script = doc.createElement('script');
    script.text = "(function f(){parent.func()})()";
    doc.body.appendChild(script);
    // Logs "function called from frame myframe"
    

答案 3 :(得分:0)

在调用父函数时,如果没有在参数中不包含此信息,就无法获得此信息。

幸运的是,这很容易。假设为每个iframe提供一个ID,则只需将iframe的ID传递给您要调用的函数即可。您可以像这样获得您所在的iframe的ID:window.frameElement.id

例如:

iframe1.html

<script>
    window.parent.printWhoCalledMe(window.frameElement.id);
</script>

parent.html

<script>
    function printWhoCalledMe(iframeId) {
        console.log(iframeId);  // Prints the id of the iframe that called the function
    }
</script>