Javascript 从窗口将值传递给iframe
我需要向iframe发送一个值 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的父窗口中使用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)。要知道何时调用该方法,您有两个选项:
<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初始化的游戏