将值传递给窗口中的iframe

时间:2009-02-11 12:20:52

标签: javascript html iframe

我需要向iframe发送一个值。

iframe存在于当前窗口中。我怎样才能做到这一点?

我需要在包含iframe的父窗口中使用javascript。

11 个答案:

答案 0 :(得分:62)

首先,您需要了解您有两个文档:框架和容器(包含框架)。

从容器操作框架的主要障碍是框架异步加载。您不能随时访问它,您必须知道它何时完成加载。所以你需要一个技巧。通常的解决方案是在框架中使用window.parent来“向上”(进入包含iframe标签的文档)。

现在您可以调用容器文档中的任何方法。此方法可以操作框架(例如,使用您需要的参数调用框架中的一些JavaScript )。要知道何时调用该方法,您有两个选择:

  1. 从框架的body.onload调用它。

  2. 将一个脚本元素放在框架的HTML内容中,您可以在其中调用容器的方法(左侧作为读者的练习)。

  3. 所以框架看起来像这样:

    <script>
    function init() { window.parent.setUpFrame(); return true; }
    function yourMethod(arg) { ... }
    </script>
    <body onload="init();">...</body>
    

    像这样的容器:

    <script>
    function setUpFrame() { 
        var frame = window.frames['frame-id'];
        frame.yourMethod('hello');
    }
    </script>
    <body><iframe name="frame-id" src="..."></iframe></body>
    

答案 1 :(得分:48)

取决于您的具体情况,但如果页面的其余部分加载后可以部署iframe,您只需使用查询字符串,即la:

<iframe src="some_page.html?somedata=5&more=bacon"></iframe>

然后在some_page.html的某处:

<script>
var params = location.href.split('?')[1].split('&');
data = {};
for (x in params)
 {
data[params[x].split('=')[0]] = params[x].split('=')[1];
 }
</script>

答案 2 :(得分:29)

这是另一个解决方案,如果帧来自不同的域,则可以使用。

var frame = /*the iframe DOM object*/;
frame.contentWindow.postMessage({call:'sendValue', value: /*value*/}, /*frame domain url or '*'*/);

在框架本身:

window.addEventListener('message', function(event) {
    var origin = event.origin || event.originalEvent.origin; // For Chrome, the origin property is in the event.originalEvent object.
    if (origin !== /*the container's domain url*/)
        return;
    if (typeof event.data == 'object' && event.data.call=='sendValue') {
        // Do something with event.data.value;
    }
}, false);

不知道哪些浏览器支持此功能。

答案 3 :(得分:13)

使用frames collection

从链接:

var frames = window.frames; // or // var frames = window.parent.frames;
for (var i = 0; i < frames.length; i++) { 
  // do something with each subframe as frames[i]
  frames[i].document.body.style.background = "red";
}

如果iframe有名称,您还可以执行以下操作:

window.frames['ponies'].number_of_ponies = 7;

如果两个页面是从同一个域提供的,则只能执行此操作。

答案 4 :(得分:11)

还有两个选项,它们不是最优雅的,但可能更容易理解和实现,特别是在iframe从其父级需要的数据只是几个变量而不是复杂对象的情况下:

使用网址片段标识符(#)

在容器中:

<iframe name="frame-id" src="http://url_to_iframe#dataToFrame"></iframe>

在iFrame中:

<script>
var dataFromDocument = location.hash.replace(/#/, "");
alert(dataFromDocument); //alerts "dataToFrame"
</script>

使用iFrame的名称

(我不喜欢这个解决方案 - 它滥用了name属性,但它是一个选项,所以我提到它的记录)

在容器中:

<iframe name="dataToFrame" src="http://url_to_iframe"></iframe>

在iFrame中:

<script type="text/javascript">
alert(window.name); // alerts "dataToFrame"
</script>

答案 5 :(得分:2)

如果您在内部使用 angular 和 iframe,则需要收听 iframe 以完成加载。你可以这样做:

         document.getElementsByTagName("iframe")[0].addEventListener('load', () => {
            document.getElementsByTagName("iframe")[0].contentWindow.postMessage(
                {
                    call: 'sendValue',
                    value: 'data'
                },
                window.location.origin)
        })

您必须以一种或另一种方式获取 iframe(有更好的方法可以在 angular 中实现),然后等待它加载。否则,即使您在 ngAfterViewInit()

等生命周期方法中执行此操作,侦听器也不会附加到它

答案 6 :(得分:0)

请看下面的链接,这表明可以使用Javascript更改页面中iFrame的内容,尽管您最有可能遇到一些跨浏览器问题。如果您可以执行此操作,则可以使用页面中的javascript将隐藏的dom元素添加到包含您的值的iFrame中,iFrame可以读取这些元素。 Accessing the document inside an iFrame

答案 7 :(得分:0)

我们可以使用“ postMessage”概念将数据从主窗口发送到基础iframe。

you can checkout more about postMessage using this link 在主窗口页面内添加以下代码

// main window code
window.frames['myFrame'].contentWindow.postMessage("Hello World!");

我们将通过“ Hello World!”消息发送到iframe id =“ myFrame”的iframe contentWindow。

现在在iframe源代码中添加以下代码

// iframe document code
function receive(event) {
    console.log("Received Message : " + event.data);
}
window.addEventListener('message', receive);

在iframe网页中,我们将附加一个事件侦听器以接收事件,并在“接收”回调中将数据打印到控制台

答案 8 :(得分:0)

您要做的是将这些值作为参数附加到iframe src(URL)中。

例如<iframe src="some_page.php?somedata=5&more=bacon"></iframe>

然后在some_page.php文件中,使用php $_GET['somedata']从iframe URL中检索它。注意:iframe在文件中作为单独的浏览器窗口运行。

答案 9 :(得分:0)

另一种方式。 从 iframe,您可以添加事件侦听器并将事件分派到父文档中:

parent.document.addEventListener('iframe-event', (e) => {
    console.log('iframe-event', e.detail);
});

setTimeout(() => {
    console.log('dispatchEvent from iframe');
    const event = new CustomEvent('frame-ready', { detail: 'parent event dispatched from iframe' });
    parent.document.dispatchEvent(event);
}, 1000);

从父级,您可以在其自己的文档中添加事件侦听器和调度事件:

document.addEventListener('frame-ready', (e) => {
        const event = new CustomEvent('iframe-event', { detail: 'iframe event dispatched from parent' });
        document.dispatchEvent(event);
    });

此外,如果您需要在新选项卡中打开此框架,您仍然可以使用事件进行通信。 从您的框架/标签:

if (opener) {
        const event = new CustomEvent('frame-ready', { detail: 'parent event dispatched from new tab' });
        opener.document.dispatchEvent(event);
    }

来自您的父母/开场白:

window.open('my-frame.html', '_blank');

document.addEventListener('frame-ready', (e) => {
    const event = new CustomEvent('iframe-event', { detail: 'iframe event dispatched from parent' });
    document.dispatchEvent(event);
});

请注意 window.open 会将您的 DOM 暴露给它打开的下一个页面,因此如果您使用它打开任何第三方 url,您必须始终使用 rel=noopener 以避免安全问题:

window.open('third-part-url.html', '_blank', 'noopener');

答案 10 :(得分:0)

在您的主页中,添加这一行-

window.postMessage("Hello data from Homepage");

在您的 iframe 中,添加这一行-

window.addEventListener("message", receiveDataFromWeb);

const receiveDataFromWeb=  (data)=> {
    console.log(data);
    //this should print Hello data from Homepage
}