2

这是一个例子

父.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>

更大的问题是,我有一个测试工具,它在 iframe 中一次运行一堆测试。每个测试调用window.parent.reportOnTest(success)

我正在研究通过在超过 1 个 iframe 中运行测试来并行化测试,但我必须通过每个测试,目前是 1000 个测试,并将它们的调用从window.parent.reportOnTest(success)类似window.parent.reportOnTest(success, window.location.href)或类似的东西更改。

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

注意:我试过

function printWhoCalledMe() {
  console.log(window.location.href);
}

但这是打印父母的href。

4

4 回答 4

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>
于 2012-11-27T10:27:51.913 回答
0

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

window.parent.printWhoCalledMe.apply(this);

function printWhoCalledMe() {
  console.log(this); // this now refers to the frame window
}
于 2012-11-27T10:29:00.220 回答
0

调用父函数时,如果不将其包含在参数中,就无法获取此信息。

幸运的是,这很容易。假设您给每个 iframe 一个 id,您只需将 iframe 的 id 传递给您正在调用的函数。您可以像这样获取您所在的 iframe 的 id window.frameElement.id

例如:

iframe1.html

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

父.html

<script>
    function printWhoCalledMe(iframeId) {
        console.log(iframeId);  // Prints the id of the iframe that called the function
    }
</script>
于 2019-06-13T23:36:53.783 回答
0

太老套了,但你可以使用这样的东西:

  1. 用于caller获取调用所需函数的函数的引用。
  2. 继续使用Object.getPrototypeOf,直到达到Object.prototype那个境界。
  3. 迭代所有框架窗口,并比较Object.prototype
  4. 找到匹配项后,使用frameElement获取 iframe。

这需要同源、无沙盒和草率模式。例子:

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"
于 2017-01-16T04:41:57.040 回答