I would like to manipulate the HTML inside an iframe using jQuery.
I thought I'd be able to do this by setting the context of the jQuery function to be the document of the iframe, something like:
$(function(){ //document ready
$('some selector', frames['nameOfMyIframe'].document).doStuff()
});
However this doesn't seem to work. A bit of inspection shows me that the variables in frames['nameOfMyIframe'] are undefined unless I wait a while for the iframe to load. However, when the iframe loads the variables are not accessible (I get permission denied-type errors).
Does anyone know of a work-around to this?
If the <iframe> is from the same domain, the elements are easily accessible as
$("#iFrame").contents().find("#someDiv").removeClass("hidden");
Reference
I think what you are doing is subject to the same origin policy. This should be the reason why you are getting permission denied type errors.
You could use .contents() method of jQuery.
The .contents() method can also be used to get the content document of an iframe, if the iframe is on the same domain as the main page.
$(document).ready(function(){
$('#frameID').load(function(){
$('#frameID').contents().find('body').html('Hey, i`ve changed content of <body>! Yay!!!');
});
});
If the iframe src is from another domain you can still do it. You need to read the external page into PHP and echo it from your domain. Like this:
iframe_page.php
<?php
$URL = "http://external.com";
$domain = file_get_contents($URL);
echo $domain;
?>
Then something like this:
display_page.html
<html>
<head>
<title>Test</title>
</head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
cleanit = setInterval ( "cleaning()", 500 );
});
function cleaning(){
if($('#frametest').contents().find('.selector').html() == "somthing"){
clearInterval(cleanit);
$('#selector').contents().find('.Link').html('ideate tech');
}
}
</script>
<body>
<iframe name="frametest" id="frametest" src="http://yourdomain.com/iframe_page.php" ></iframe>
</body>
</html>
The above is an example of how to edit an external page through an iframe without the access denied etc...
Use
iframe.contentWindow.document
instead of
iframe.contentDocument
I find this way cleaner:
var $iframe = $("#iframeID").contents();
$iframe.find('selector');
You need to attach an event to an iframe's onload handler, and execute the js in there, so that you make sure the iframe has finished loading before accessing it.
$().ready(function () {
$("#iframeID").ready(function () { //The function below executes once the iframe has finished loading
$('some selector', frames['nameOfMyIframe'].document).doStuff();
});
};
The above will solve the 'not-yet-loaded' problem, but as regards the permissions, if you are loading a page in the iframe that is from a different domain, you won't be able to access it due to security restrictions.
You can use window.postMessage to call a function between page and his iframe (cross domain or not).
Documentation
page.html
<!DOCTYPE html>
<html>
<head>
<title>Page with an iframe</title>
<meta charset="UTF-8" />
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script>
var Page = {
id:'page',
variable:'This is the page.'
};
$(window).on('message', function(e) {
var event = e.originalEvent;
if(window.console) {
console.log(event);
}
alert(event.origin + '\n' + event.data);
});
function iframeReady(iframe) {
if(iframe.contentWindow.postMessage) {
iframe.contentWindow.postMessage('Hello ' + Page.id, '*');
}
}
</script>
</head>
<body>
<h1>Page with an iframe</h1>
<iframe src="iframe.html" onload="iframeReady(this);"></iframe>
</body>
</html>
iframe.html
<!DOCTYPE html>
<html>
<head>
<title>iframe</title>
<meta charset="UTF-8" />
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script>
var Page = {
id:'iframe',
variable:'The iframe.'
};
$(window).on('message', function(e) {
var event = e.originalEvent;
if(window.console) {
console.log(event);
}
alert(event.origin + '\n' + event.data);
});
$(window).on('load', function() {
if(window.parent.postMessage) {
window.parent.postMessage('Hello ' + Page.id, '*');
}
});
</script>
</head>
<body>
<h1>iframe</h1>
<p>It's the iframe.</p>
</body>
</html>
I prefer to use other variant for accessing.
From parent you can have a access to variable in child iframe.
$ is a variable too and you can receive access to its just call
window.iframe_id.$
For example, window.view.$('div').hide() - hide all divs in iframe with id 'view'
But, it doesn't work in FF. For better compatibility you should use
$('#iframe_id')[0].contentWindow.$
Have you tried the classic, waiting for the load to complete using jQuery's builtin ready function?
$(document).ready(function() {
$('some selector', frames['nameOfMyIframe'].document).doStuff()
} );
K
I create a sample code . Now you can easily understand from different domain you can't access
content of iframe .. Same domain we can access iframe content
I share you my code , Please run this code
check the console . I print image src at console. There are four iframe , two iframe coming from same domain & other two from other domain(third party) .You can see two image src( https://www.google.com/logos/doodles/2015/googles-new-logo-5078286822539264.3-hp2x.gif
and
https://www.google.com/logos/doodles/2015/arbor-day-2015-brazil-5154560611975168-hp2x.gif
)
at console and also can see two permission error(
2
Error: Permission denied to access property 'document'
...irstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument...
) which is coming from third party iframe.
<body id="page-top" data-spy="scroll" data-target=".navbar-fixed-top">
<p>iframe from same domain</p>
<iframe frameborder="0" scrolling="no" width="500" height="500"
src="iframe.html" name="imgbox" class="iView">
</iframe>
<p>iframe from same domain</p>
<iframe frameborder="0" scrolling="no" width="500" height="500"
src="iframe2.html" name="imgbox" class="iView1">
</iframe>
<p>iframe from different domain</p>
<iframe frameborder="0" scrolling="no" width="500" height="500"
src="https://www.google.com/logos/doodles/2015/googles-new-logo-5078286822539264.3-hp2x.gif" name="imgbox" class="iView2">
</iframe>
<p>iframe from different domain</p>
<iframe frameborder="0" scrolling="no" width="500" height="500"
src="http://d1rmo5dfr7fx8e.cloudfront.net/" name="imgbox" class="iView3">
</iframe>
<script type='text/javascript'>
$(document).ready(function(){
setTimeout(function(){
var src = $('.iView').contents().find(".shrinkToFit").attr('src');
console.log(src);
}, 2000);
setTimeout(function(){
var src = $('.iView1').contents().find(".shrinkToFit").attr('src');
console.log(src);
}, 3000);
setTimeout(function(){
var src = $('.iView2').contents().find(".shrinkToFit").attr('src');
console.log(src);
}, 3000);
setTimeout(function(){
var src = $('.iView3').contents().find("img").attr('src');
console.log(src);
}, 3000);
})
</script>
</body>
If the code below doesn't work
$("#iFrame").contents().find("#someDiv").removeClass("hidden");
Here is the reliable way to make it work:
$(document).ready(function(){
setTimeout(
function () {
$("#iFrame").contents().find("#someDiv").removeClass("hidden");
},
300
);
});
This way the script will run after 300 miliseconds, so it'll get enough time for iFrame to be loaded and then the code will come into action. At times the iFrame doesn't load and script tries to execute before it. 300ms can be tweaked to anything else as per your needs.
For even more robustness:
function getIframeWindow(iframe_object) {
var doc;
if (iframe_object.contentWindow) {
return iframe_object.contentWindow;
}
if (iframe_object.window) {
return iframe_object.window;
}
if (!doc && iframe_object.contentDocument) {
doc = iframe_object.contentDocument;
}
if (!doc && iframe_object.document) {
doc = iframe_object.document;
}
if (doc && doc.defaultView) {
return doc.defaultView;
}
if (doc && doc.parentWindow) {
return doc.parentWindow;
}
return undefined;
}
and
...
var frame_win = getIframeWindow( frames['nameOfMyIframe'] );
if (frame_win) {
$(frame_win.contentDocument || frame_win.document).find('some selector').doStuff();
...
}
...
I ended up here looking for getting the content of an iframe without jquery, so for anyone else looking for that, it is just this:
document.querySelector('iframe[name=iframename]').contentDocument
This solution works same as iFrame. I have created a PHP script that can get all the contents from the other website, and most important part is you can easily apply your custom jQuery to that external content. Please refer to the following script that can get all the contents from the other website and then you can apply your cusom jQuery/JS as well. This content can be used anywhere, inside any element or any page.
<div id='myframe'>
<?php
/*
Use below function to display final HTML inside this div
*/
//Display Frame
echo displayFrame();
?>
</div>
<?php
/*
Function to display frame from another domain
*/
function displayFrame()
{
$webUrl = 'http://[external-web-domain.com]/';
//Get HTML from the URL
$content = file_get_contents($webUrl);
//Add custom JS to returned HTML content
$customJS = "
<script>
/* Here I am writing a sample jQuery to hide the navigation menu
You can write your own jQuery for this content
*/
//Hide Navigation bar
jQuery(\".navbar.navbar-default\").hide();
</script>";
//Append Custom JS with HTML
$html = $content . $customJS;
//Return customized HTML
return $html;
}
Related
I would like to manipulate the HTML inside an iframe using jQuery.
I thought I'd be able to do this by setting the context of the jQuery function to be the document of the iframe, something like:
$(function(){ //document ready
$('some selector', frames['nameOfMyIframe'].document).doStuff()
});
However this doesn't seem to work. A bit of inspection shows me that the variables in frames['nameOfMyIframe'] are undefined unless I wait a while for the iframe to load. However, when the iframe loads the variables are not accessible (I get permission denied-type errors).
Does anyone know of a work-around to this?
If the <iframe> is from the same domain, the elements are easily accessible as
$("#iFrame").contents().find("#someDiv").removeClass("hidden");
Reference
I think what you are doing is subject to the same origin policy. This should be the reason why you are getting permission denied type errors.
You could use .contents() method of jQuery.
The .contents() method can also be used to get the content document of an iframe, if the iframe is on the same domain as the main page.
$(document).ready(function(){
$('#frameID').load(function(){
$('#frameID').contents().find('body').html('Hey, i`ve changed content of <body>! Yay!!!');
});
});
If the iframe src is from another domain you can still do it. You need to read the external page into PHP and echo it from your domain. Like this:
iframe_page.php
<?php
$URL = "http://external.com";
$domain = file_get_contents($URL);
echo $domain;
?>
Then something like this:
display_page.html
<html>
<head>
<title>Test</title>
</head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
cleanit = setInterval ( "cleaning()", 500 );
});
function cleaning(){
if($('#frametest').contents().find('.selector').html() == "somthing"){
clearInterval(cleanit);
$('#selector').contents().find('.Link').html('ideate tech');
}
}
</script>
<body>
<iframe name="frametest" id="frametest" src="http://yourdomain.com/iframe_page.php" ></iframe>
</body>
</html>
The above is an example of how to edit an external page through an iframe without the access denied etc...
Use
iframe.contentWindow.document
instead of
iframe.contentDocument
I find this way cleaner:
var $iframe = $("#iframeID").contents();
$iframe.find('selector');
You need to attach an event to an iframe's onload handler, and execute the js in there, so that you make sure the iframe has finished loading before accessing it.
$().ready(function () {
$("#iframeID").ready(function () { //The function below executes once the iframe has finished loading
$('some selector', frames['nameOfMyIframe'].document).doStuff();
});
};
The above will solve the 'not-yet-loaded' problem, but as regards the permissions, if you are loading a page in the iframe that is from a different domain, you won't be able to access it due to security restrictions.
You can use window.postMessage to call a function between page and his iframe (cross domain or not).
Documentation
page.html
<!DOCTYPE html>
<html>
<head>
<title>Page with an iframe</title>
<meta charset="UTF-8" />
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script>
var Page = {
id:'page',
variable:'This is the page.'
};
$(window).on('message', function(e) {
var event = e.originalEvent;
if(window.console) {
console.log(event);
}
alert(event.origin + '\n' + event.data);
});
function iframeReady(iframe) {
if(iframe.contentWindow.postMessage) {
iframe.contentWindow.postMessage('Hello ' + Page.id, '*');
}
}
</script>
</head>
<body>
<h1>Page with an iframe</h1>
<iframe src="iframe.html" onload="iframeReady(this);"></iframe>
</body>
</html>
iframe.html
<!DOCTYPE html>
<html>
<head>
<title>iframe</title>
<meta charset="UTF-8" />
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script>
var Page = {
id:'iframe',
variable:'The iframe.'
};
$(window).on('message', function(e) {
var event = e.originalEvent;
if(window.console) {
console.log(event);
}
alert(event.origin + '\n' + event.data);
});
$(window).on('load', function() {
if(window.parent.postMessage) {
window.parent.postMessage('Hello ' + Page.id, '*');
}
});
</script>
</head>
<body>
<h1>iframe</h1>
<p>It's the iframe.</p>
</body>
</html>
I prefer to use other variant for accessing.
From parent you can have a access to variable in child iframe.
$ is a variable too and you can receive access to its just call
window.iframe_id.$
For example, window.view.$('div').hide() - hide all divs in iframe with id 'view'
But, it doesn't work in FF. For better compatibility you should use
$('#iframe_id')[0].contentWindow.$
Have you tried the classic, waiting for the load to complete using jQuery's builtin ready function?
$(document).ready(function() {
$('some selector', frames['nameOfMyIframe'].document).doStuff()
} );
K
I create a sample code . Now you can easily understand from different domain you can't access
content of iframe .. Same domain we can access iframe content
I share you my code , Please run this code
check the console . I print image src at console. There are four iframe , two iframe coming from same domain & other two from other domain(third party) .You can see two image src( https://www.google.com/logos/doodles/2015/googles-new-logo-5078286822539264.3-hp2x.gif
and
https://www.google.com/logos/doodles/2015/arbor-day-2015-brazil-5154560611975168-hp2x.gif
)
at console and also can see two permission error(
2
Error: Permission denied to access property 'document'
...irstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument...
) which is coming from third party iframe.
<body id="page-top" data-spy="scroll" data-target=".navbar-fixed-top">
<p>iframe from same domain</p>
<iframe frameborder="0" scrolling="no" width="500" height="500"
src="iframe.html" name="imgbox" class="iView">
</iframe>
<p>iframe from same domain</p>
<iframe frameborder="0" scrolling="no" width="500" height="500"
src="iframe2.html" name="imgbox" class="iView1">
</iframe>
<p>iframe from different domain</p>
<iframe frameborder="0" scrolling="no" width="500" height="500"
src="https://www.google.com/logos/doodles/2015/googles-new-logo-5078286822539264.3-hp2x.gif" name="imgbox" class="iView2">
</iframe>
<p>iframe from different domain</p>
<iframe frameborder="0" scrolling="no" width="500" height="500"
src="http://d1rmo5dfr7fx8e.cloudfront.net/" name="imgbox" class="iView3">
</iframe>
<script type='text/javascript'>
$(document).ready(function(){
setTimeout(function(){
var src = $('.iView').contents().find(".shrinkToFit").attr('src');
console.log(src);
}, 2000);
setTimeout(function(){
var src = $('.iView1').contents().find(".shrinkToFit").attr('src');
console.log(src);
}, 3000);
setTimeout(function(){
var src = $('.iView2').contents().find(".shrinkToFit").attr('src');
console.log(src);
}, 3000);
setTimeout(function(){
var src = $('.iView3').contents().find("img").attr('src');
console.log(src);
}, 3000);
})
</script>
</body>
If the code below doesn't work
$("#iFrame").contents().find("#someDiv").removeClass("hidden");
Here is the reliable way to make it work:
$(document).ready(function(){
setTimeout(
function () {
$("#iFrame").contents().find("#someDiv").removeClass("hidden");
},
300
);
});
This way the script will run after 300 miliseconds, so it'll get enough time for iFrame to be loaded and then the code will come into action. At times the iFrame doesn't load and script tries to execute before it. 300ms can be tweaked to anything else as per your needs.
For even more robustness:
function getIframeWindow(iframe_object) {
var doc;
if (iframe_object.contentWindow) {
return iframe_object.contentWindow;
}
if (iframe_object.window) {
return iframe_object.window;
}
if (!doc && iframe_object.contentDocument) {
doc = iframe_object.contentDocument;
}
if (!doc && iframe_object.document) {
doc = iframe_object.document;
}
if (doc && doc.defaultView) {
return doc.defaultView;
}
if (doc && doc.parentWindow) {
return doc.parentWindow;
}
return undefined;
}
and
...
var frame_win = getIframeWindow( frames['nameOfMyIframe'] );
if (frame_win) {
$(frame_win.contentDocument || frame_win.document).find('some selector').doStuff();
...
}
...
I ended up here looking for getting the content of an iframe without jquery, so for anyone else looking for that, it is just this:
document.querySelector('iframe[name=iframename]').contentDocument
This solution works same as iFrame. I have created a PHP script that can get all the contents from the other website, and most important part is you can easily apply your custom jQuery to that external content. Please refer to the following script that can get all the contents from the other website and then you can apply your cusom jQuery/JS as well. This content can be used anywhere, inside any element or any page.
<div id='myframe'>
<?php
/*
Use below function to display final HTML inside this div
*/
//Display Frame
echo displayFrame();
?>
</div>
<?php
/*
Function to display frame from another domain
*/
function displayFrame()
{
$webUrl = 'http://[external-web-domain.com]/';
//Get HTML from the URL
$content = file_get_contents($webUrl);
//Add custom JS to returned HTML content
$customJS = "
<script>
/* Here I am writing a sample jQuery to hide the navigation menu
You can write your own jQuery for this content
*/
//Hide Navigation bar
jQuery(\".navbar.navbar-default\").hide();
</script>";
//Append Custom JS with HTML
$html = $content . $customJS;
//Return customized HTML
return $html;
}
I am trying to loop over all existing iframes by checking their attribute (name). In case it matches the name, I would like to set a src value.
<iframe name="test1" src="" />
<iframe name="test2" src="" />
<iframe name="test3" src="" />
<script>
$(document).ready(function(e) {
var frames = document.getElementByTagName('iframe');
for (var i in frames) {
if (frames[i].name.match(/test1/g)) {
iframes[i].attr('src', 'http://testing1.com/');
}
if (frames[i].name.match(/test2/g)) {
iframes[i].attr('src', 'http://testing2.com/');
}
}
};
</script>
would anyone help me to fix the code to make it valid?
I'm answering also if this already got an answer. This was it, vanilla js:
var selection = document.getElementsByTagName('iframe');
var iframes = Array.prototype.slice.call(selection);
iframes.forEach(function(iframe) {
if (iframe.name.match(/test1/g)) {
iframe.setAttribute("src", "http://testing1.com/");
} else if (iframe.name.match(/test2/g)) {
iframe.setAttribute("src", "http://testing2.com/");
} else if (iframe.name.match(/test3/g)) {
iframe.setAttribute("src", "http://testing3.com/");
}
});
JSFiddle here.
Well, the function is getElementsByTagName (in plural). You're also mixing jQuery functions with native DOM elements, which won't work. But since you're using jQuery anyway, you might as well use it for all of the code:
<script>
$('iframe[name="test1"]').attr('src', 'testing1.com')
$('iframe[name="test2"]').attr('src', 'testing2.com')
</script>
Edit: also, iframes are not self closing tags, so you're going to get weird behaviour if you use <iframe /> like you did in your post. You should close the tag explicitly: <iframe></iframe>
A working example;
$(document).ready(function(e) {
$('iframe').each(function() {
if ($(this).attr('name') == "test1")
$(this).attr('src', 'https://www.domain1.com');
if ($(this).attr('name') == "test2")
$(this).attr('src', 'https://www.domain2.com');
if ($(this).attr('name') == "test3")
$(this).attr('src', 'https://www.domain3.com');
});
});
<iframe name="test1"></iframe>
<br>
<iframe name="test2"></iframe>
<br>
<iframe name="test3"></iframe>
Fiddle: https://jsfiddle.net/v760e5zq/
I have a unique issue that--while I've seen similar questions and answers--none quite address my challenge.
Currently, I provide a "print" button that loads the print dialog on a browser based on an embedded and hidden iframe. This works just fine, but I don't want to slow down page loading by pulling in the iframe for a large PDF.
So, I want to load an iframe without the source, then write the proper source url if the user clicks the print icon, then reload the iframe, and finally, show the dialog box.
Unfortunately, the print dialog pops up before I can reload the iframe so loads a blank page in the dialog box. On subsequent clicks, the PDF is loaded and ready for print.
<a href='#' id='load_pdf' ><i class='fa fa-2 fa-print'></i></a>
<iframe id="iFramePdf" src="" style="display:none;"></iframe>
<script type="text/javascript">
jQuery(document).ready(function() {
$("#load_pdf").click(loadPDF);
function loadPDF() {
$('#iFramePdf').attr('src', "my.pdf");
// Attempt to reload iframe
$('#iFramePdf').load("my.pdf");
sendPrint('iFramePdf')
}
function sendPrint(elementId) {
var iframe = $(element_id)[0];
iframe.contentWindow.focus();
iframe.contentWindow.print();
}
});
</script>
I've tried the following various methods to reload:
// Attempt 1
$('#iFramePdf').attr('src', function () { return
$(this).contents().get(0).location.href });
// Attempt 2
$('#iFramePdf').attr("src", $('#iFramePdf').attr("src"));
$('#iFramePdf').attr('src', function () { return $(this).contents().get(0).location.href });
// Attempt 3
$('#iFramePdf')[0].contentWindow.location.reload(true);
// Attempt 4
var getMyFrame = document.getElementById(elementId);
getMyFrame.contentWindow.location.reload(true);
I've even tried using jQuery's defer method, but had no luck with that (possibly because I'm lacking knowledge). If I could get any guidance, I'd appreciate it.
try to change this:
function loadPDF() {
$('#iFramePdf').attr('src', "my.pdf");
// Attempt to reload iframe
$('#iFramePdf').load("my.pdf");
sendPrint('iFramePdf')
}
to something like this:
function loadPDF() {
$('#iFramePdf').attr('src', "my.pdf");
}
$('#iFramePdf').load(function(){
sendPrint('iFramePdf')
})
it should work
You can try .promise(). For obvious reasons I can't test it out, but I think 3 seconds should be adequate for the iframe to load. Be aware that this is as syntactically correct as I can get it without testing it out. Adjust the fadeIn(1800) and the delay(1200) accordingly.
HTML
<a href='#' id='load_pdf' ><i class='fa fa-2 fa-print'></i></a>
<p id="msg" style="display: none;">Printing Document...</p>
<div id="printPort" style="opacity: 0; width: 1px; height: 1px;"></div>
jQuery
$(function() {
$("#load_pdf").on('click', loadPDF('my.pdf'));
// Create the iframe, and put it inside #printPort
// Change it's src to the file argument
// Animate the #msg for 3 seconds
var loadPDF = function(file) {
$('<iframe id="iFramePdf" src="blank.html"></iframe>').appendTo("#printPort");
$("#iFramePdf").att('src', file);
return $('#msg').fadeIn(1800).delay(1200).fadeOut();
}
var sendPrint = function(elementId) {
var iframe = $(element_id)[0];
iframe.contentWindow.focus();
iframe.contentWindow.print();
}
// Once the animation is done the promise will resolve and sendPrint will execute on callback.
$.when(loadPDF).done(sendPrint('iFramePdf'));
});
I'm using postMessage to push the parent page css to the page within each iframe. The issue is that there may be more than 1 iframe already on the page before this code is applied. Therefore, how can I apply the postMessage specifically to the id of each frame, instead of having to manually enter window.frames[0] and window.frames[1], where [] is adjusted based on the page.
iframe
<iframe id="frame1" style="width: 100%; height: 420px;" src="../syndicatedPlayer.html#videoUrl=http://video.mp4?" frameborder="0"></iframe>
<iframe id="frame2" style="width: 100%; height: 420px;" src="../syndicatedPlayer.html#videoUrl=http://video.mp4?" frameborder="0"></iframe>
postMessage()
<script type="text/javascript">
var getFontFamily = function() {
var el = document.getElementsByTagName("h1")[0];
var cs = window.getComputedStyle(el, null);
return cs.fontFamily;
}
window.addEventListener('load', function(){
var data = getFontFamily("h1");
window.frames[0].postMessage(data, 'http://url.html');
window.frames[1].postMessage(data, 'http://url.html');
console.log('Message sent -->');
});
</script>
Actually, window===window.frames, so you can just use window[0] to obtain the frame.
Said that, a way to obtain an iframe by its id is the following function:
function getFrameById(id) {
for (var i=0;i<window.length;i++) {
if (window[i].frameElement.id===id) return window[i];
}
return null;
}
Update: I've fixed and completed you fiddle: http://jsfiddle.net/9qtcmbnn/4/
you can specify which iframe you will use by selecting it by id and then postmessage the data you want from it
you can use it as below
<script>
function test1() {
document.getElementById('idMyIframe1').contentWindow.postMessage("your message here", "*");
}
function test2() {
document.getElementById('idMyIframe2').contentWindow.postMessage("your message here", "*");
}
</script>
<iframe id="idMyIframe1" onload="test1()" src="http://example.otherdomaintosenddatato.com"></iframe>
<iframe id="idMyIframe2" onload="test2()" src="http://example.otherdomaintosenddatato.com"></iframe>
In my background (background.html) page I have the following js:
function capturePage(){
chrome.tabs.captureVisibleTab(null, function(img){
var screenshotUrl = img;
chrome.tabs.create({"url":"history.html"}, function(tab){
var t = tab;
var addImage = function(){
var view = chrome.extension.getViews()[0];
view.setImageUrl(screenshotUrl);
}
chrome.tabs.onUpdated.addListener(addImage);
});
});
}
chrome.browserAction.onClicked.addListener(capturePage);
and in history.html I have:
<html>
<head>
<title></title>
<script>
function setImageUrl(url){
document.getElementById("target").src = url;
}
</script>
</head>
<body>
<img id="target" src="" >
</body>
</html>
However, "view.setImageUrl(screenshotUrl)", in background.html, fails as it says the view has no such function. Just to be clear, I'm trying to access a function within history.html AND pass a parameter to it (screenshotUrl).
EDIT: re Serg's suggestion I replaced the var addImage function in background with the following:
var port = chrome.tabs.connect(tab.id,{name: "history_connect"});
port.postMessage({mType:"url",url:screenshotUrl});
Then added a listener on the history page... worked!
I haven't used getViews() before so I can't comment on that (what does console say when you dump chrome.extension.getViews() into it?), but here is couple workarounds:
Pass your url as get parameter during tab creation (history.html?url=<urlencoded_url>)
Use requests. chrome.extension.sendRequest({url:url}); in bkgd page and chrome.extension.onRequest.addListener() in history.html
Use "pull" instead of "push". In history.html you can use chrome.extension.getBackgroundPage().getMyUrl()
I would use the first solution as it is the easiest and fastest.