Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/463.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从窗口将值传递给iframe_Javascript_Html_Iframe - Fatal编程技术网

Javascript 从窗口将值传递给iframe

Javascript 从窗口将值传递给iframe,javascript,html,iframe,Javascript,Html,Iframe,我需要向iframe发送一个值 iframe存在于当前窗口中。我怎样才能做到这一点 我需要在包含iframe的父窗口中使用javascript来完成此操作。查看下面的链接,这表明可以使用javascript更改页面中iframe的内容,尽管您很可能会遇到一些跨浏览器问题。如果可以做到这一点,您可以使用页面中的javascript将隐藏的dom元素添加到包含您的值的iFrame中,iFrame可以读取这些值。 使用 从链接: var frames = window.frames; // or //

我需要向iframe发送一个值

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


我需要在包含iframe的父窗口中使用javascript来完成此操作。

查看下面的链接,这表明可以使用javascript更改页面中iframe的内容,尽管您很可能会遇到一些跨浏览器问题。如果可以做到这一点,您可以使用页面中的javascript将隐藏的dom元素添加到包含您的值的iFrame中,iFrame可以读取这些值。

使用

从链接:

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,则只需使用查询字符串,即la:

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

然后在某个页面的某个地方:

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

var params=location.href.split('?')[1].split('&');
数据={};
用于(参数中的x)
{
数据[params[x]。拆分('=')[0]]=params[x]。拆分('=')[1];
}

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

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

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

  • 从body.onload调用它

  • 将脚本元素作为最后一件事放入框架的HTML内容中,在该框架中调用容器的方法(留给读者作为练习)

  • 因此,框架如下所示:

    <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>
    
             document.getElementsByTagName("iframe")[0].addEventListener('load', () => {
                document.getElementsByTagName("iframe")[0].contentWindow.postMessage(
                    {
                        call: 'sendValue',
                        value: 'data'
                    },
                    window.location.origin)
            })
    
    
    函数init(){window.parent.setUpFrame();返回true;}
    函数方法(arg){…}
    ...
    
    容器是这样的:

    <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>
    
             document.getElementsByTagName("iframe")[0].addEventListener('load', () => {
                document.getElementsByTagName("iframe")[0].contentWindow.postMessage(
                    {
                        call: 'sendValue',
                        value: 'data'
                    },
                    window.location.origin)
            })
    
    
    函数setUpFrame(){
    var frame=window.frames['frame-id'];
    frame.yourMethod('hello');
    }
    
    还有两个选项,它们不是最优雅的,但可能更容易理解和实现,尤其是在iframe需要从其父对象获取的数据只是几个变量而不是复杂对象的情况下:

    使用URL片段标识符(#)

    在容器中:

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

    <script>
    var dataFromDocument = location.hash.replace(/#/, "");
    alert(dataFromDocument); //alerts "dataToFrame"
    </script>
    
    <script type="text/javascript">
    alert(window.name); // alerts "dataToFrame"
    </script>
    
    
    var dataFromDocument=location.hash.replace(/#/,“”);
    警报(数据来自文档)//警报“dataToFrame”
    
    使用iFrame的名称

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

    在容器中:

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

    <script>
    var dataFromDocument = location.hash.replace(/#/, "");
    alert(dataFromDocument); //alerts "dataToFrame"
    </script>
    
    <script type="text/javascript">
    alert(window.name); // alerts "dataToFrame"
    </script>
    
    
    警报(窗口名称);//警报“dataToFrame”
    
    如果帧来自不同的域,则可以使用另一种解决方案。

    var frame=/*iframe DOM对象*/;
    frame.contentWindow.postMessage({call:'sendValue',value:/*value*/},/*frame域url或'*'*/);
    
    在框架中:

    window.addEventListener('message',函数(事件){
    var origin=event.origin | | event.originalEvent.origin;//对于Chrome,origin属性位于event.originalEvent对象中。
    if(来源!=/*容器的域url*/)
    返回;
    if(typeof event.data=='object'&&event.data.call=='sendValue'){
    //用event.data.value做一些事情;
    }
    },假);
    
    但是,不知道哪些浏览器支持此功能。

    我们可以使用“postMessage”概念从主窗口向底层iframe发送数据

    在主窗口页面中添加以下代码

    // main window code
    window.frames['myFrame'].contentWindow.postMessage("Hello World!");
    
    我们将通过iframe id=“myFrame”将“helloworld!”消息传递给iframe contentWindow

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

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

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

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

    例如,


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

    如果在文件中使用angular和iframe,则需要监听iframe以完成加载。您可以这样做:

    <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>
    
             document.getElementsByTagName("iframe")[0].addEventListener('load', () => {
                document.getElementsByTagName("iframe")[0].contentWindow.postMessage(
                    {
                        call: 'sendValue',
                        value: 'data'
                    },
                    window.location.origin)
            })
    
    您必须以这样或那样的方式获取iframe(有更好的方式以角度进行),然后等待它加载。否则,即使您在生命周期方法(如
    ngAfterViewInit()

    中)中执行此操作,侦听器也不会附加到它。 从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);
        });
    
    从父级,您可以在其自己的文档中添加事件侦听器和分派事件:

    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');
    

    在主主页中,添加此行-

    window.postMessage("Hello data from Homepage");
    
    window.addEventListener("message", receiveDataFromWeb);
    
    const receiveDataFromWeb=  (data)=> {
        console.log(data);
        //this should print Hello data from Homepage
    }
    
    在iframe中,添加这一行-

    window.postMessage("Hello data from Homepage");
    
    window.addEventListener("message", receiveDataFromWeb);
    
    const receiveDataFromWeb=  (data)=> {
        console.log(data);
        //this should print Hello data from Homepage
    }
    

    伙计,我要感谢你的回答——它解决了一个关键的问题!如果你给这个问题添加一个答案,我会把它标记为正确:对于这个问题,这是最容易实现的答案。我推荐它。但这受到特定浏览器上URL的最大长度的限制:(最好的部分是::它适用于跨域。最适合创建可以在不同站点使用di初始化的游戏