I need to send a value to an iframe.
The iframe is present within the current window. How can I achieve this?
I need to do it with javascript in the parent window that contains the iframe.
I need to send a value to an iframe.
The iframe is present within the current window. How can I achieve this?
I need to do it with javascript in the parent window that contains the iframe.
Depends on your specific situation, but if the iframe can be deployed after the rest of the page's loading, you can simply use a query string, a la:
<iframe src="some_page.html?somedata=5&more=bacon"></iframe>
And then somewhere in 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>
location.search
to get all the query parameters including the ?
. –
Trashy First, you need to understand that you have two documents: The frame and the container (which contains the frame).
The main obstacle with manipulating the frame from the container is that the frame loads asynchronously. You can't simply access it any time, you must know when it has finished loading. So you need a trick. The usual solution is to use window.parent
in the frame to get "up" (into the document which contains the iframe
tag).
Now you can call any method in the container document. This method can manipulate the frame (for example call some JavaScript in the frame with the parameters you need). To know when to call the method, you have two options:
Call it from body.onload of the frame.
Put a script element as the last thing into the HTML content of the frame where you call the method of the container (left as an exercise for the reader).
So the frame looks like this:
<script>
function init() { window.parent.setUpFrame(); return true; }
function yourMethod(arg) { ... }
</script>
<body onload="init();">...</body>
And the container like this:
<script>
function setUpFrame() {
var frame = window.frames['frame-id'].contentWindow;
frame.yourMethod('hello');
}
</script>
<body><iframe name="frame-id" src="..."></iframe></body>
id
then I have to access it through contentWindow
in window.frames['frame-id'].contentWindow
MDN –
Plectognath Here's another solution, usable if the frames are from different domains.
var frame = /*the iframe DOM object*/;
frame.contentWindow.postMessage({call:'sendValue', value: /*value*/}, /*frame domain url or '*'*/);
And in the frame itself:
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);
Don't know which browsers support this, though.
event.originalEvent.origin
bit for Chrome is outdated; my testing with Chrome 79 in December 2019 shows that it uses event.origin
. –
Nsf Two more options, which are not the most elegant but probably easier to understand and implement, especially in case the data that the iframe needs from its parent is just a few vars, not complex objects:
Using the URL Fragment Identifier (#)
In the container:
<iframe name="frame-id" src="http://url_to_iframe#dataToFrame"></iframe>
In the iFrame:
<script>
var dataFromDocument = location.hash.replace(/#/, "");
alert(dataFromDocument); //alerts "dataToFrame"
</script>
Use the iFrame's name
(I don't like this solution - it's abusing the name attribute, but it's an option so I'm mentioning it for the record)
In the container:
<iframe name="dataToFrame" src="http://url_to_iframe"></iframe>
In the iFrame:
<script type="text/javascript">
alert(window.name); // alerts "dataToFrame"
</script>
Use the frames collection.
From the link:
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";
}
If the iframe has a name you may also do the following:
window.frames['ponies'].number_of_ponies = 7;
You can only do this if the two pages are served from the same domain.
number_of_ponies
inside the iframe? I feel I'm missing something obvious :/ –
Treachery We can use "postMessage" concept for sending data to an underlying iframe from main window.
you can checkout more about postMessage using this link add the below code inside main window page
// main window code
window.frames['myFrame'].contentWindow.postMessage("Hello World!");
we will pass "Hello World!" message to an iframe contentWindow with iframe id="myFrame".
now add the below code inside iframe source code
// iframe document code
function receive(event) {
console.log("Received Message : " + event.data);
}
window.addEventListener('message', receive);
in iframe webpage we will attach an event listener to receive event and in 'receive' callback we will print the data to console
Incase you're using angular and an iframe inside, you'll need need to listen to the iframe to finish loading. You can do something like this:
document.getElementsByTagName("iframe")[0].addEventListener('load', () => {
document.getElementsByTagName("iframe")[0].contentWindow.postMessage(
{
call: 'sendValue',
value: 'data'
},
window.location.origin)
})
You will have to get the iframe one way or another (there are better ways to do it in angular) and then wait for it to load. Or else the listener won't be attached to it even if you do it inside lifecycle methods like ngAfterViewInit()
Have a look at the link below, which suggests it is possible to alter the contents of an iFrame within your page with Javascript, although you are most likely to run into a few cross browser issues. If you can do this you can use the javascript in your page to add hidden dom elements to the iFrame containing your values, which the iFrame can read. Accessing the document inside an iFrame
Just another way. From iframe you can add event listeners and dispatch events into parent document:
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);
And from parent you can add event listeners and dispatch events in its own document:
document.addEventListener('frame-ready', (e) => {
const event = new CustomEvent('iframe-event', { detail: 'iframe event dispatched from parent' });
document.dispatchEvent(event);
});
Also if in any case you need to open this frame in a new tab you can still use events for communication. From your frame/tab:
if (opener) {
const event = new CustomEvent('frame-ready', { detail: 'parent event dispatched from new tab' });
opener.document.dispatchEvent(event);
}
From your parent/opener:
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);
});
Just be aware that window.open will expose your DOM to next page it opens, so if you use it to open any third part url, you must always use rel=noopener to avoid security issues:
window.open('third-part-url.html', '_blank', 'noopener');
In your main homepage, add this line-
window.postMessage("Hello data from Homepage");
Inside your iframe , add this line-
window.addEventListener("message", receiveDataFromWeb);
const receiveDataFromWeb= (data)=> {
console.log(data);
//this should print Hello data from Homepage
}
What you have to do is to append the values as parameters in the iframe src (URL).
E.g. <iframe src="some_page.php?somedata=5&more=bacon"></iframe>
And then in some_page.php
file you use php $_GET['somedata']
to retrieve it from the iframe URL. NB: Iframes run as a separate browser window in your file.
<html>
<head>
<title>Host</title>
<script type="text/javascript">
function send() {
const frame = document.getElementById("ifrm");
frame.contentWindow.postMessage({call:'sendValue', value: "test"}, '*');
}
</script>
</head>
<body>
Hi I am host
<iframe id="ifrm" src="http://localhost:8001/Desktop/Explisoft.com/temp/iframe.html"></iframe>
<button onclick="send()">Send message</button>
</body>
<html>
<head>
<title>IFrame</title>
</head>
<body>
Hi I am iframe
</body>
<script type="text/javascript">
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 !== "http://localhost:8000")
return;
if (typeof event.data == 'object' && event.data.call=='sendValue') {
console.log(event.data);
}
}, false);
</script>
© 2022 - 2024 — McMap. All rights reserved.