How to get notified about IFRAME appended dynamically and loaded? - javascript

I need to add an ability to a Firefox extension to handle cases when IFRAME elements are being added dynamically. Is there a way to get notified when IFRAME document is loaded in such a case?
For example:
<html>
<head>
<title>iframe test</title>
<script type="text/javascript">
function addIFrame() {
var ifrm = document.createElement("iframe");
ifrm.setAttribute("src", " http://www.google.com/");
document.body.appendChild(ifrm);
}
setTimeout('addIFrame()', 3000);
</script>
</head>
<body>
<p>A new <iframe> will be added in 3 seconds:</p>
</body>
</html>

You can set a capturing load listener on the tabbrowser and then check that the event's target is an <html:iframe>.

Related

How to access html elements in iframe inside html tag

I have a html file which contains iframe like below lines of code. Note that this iframe is displayed by one of tiny mce jquery and is rendered in browser as
below
<html>
<body>
<textarea id="texteditor"></textarea>
<div class="mceeditor">
<iframe>
<html>
<body>
<script type="text/javascript">
function mySubmit() {
var URL = "http://localhost:61222/14CommunityImages/hands.png";
window.document.getElementById("texteditor").value = URL;
}
</script>
</body>
</html>
</iframe>
</div>
</body>
</html>
Now my goal is to append var url inside text area which is in parent html tag.
Please help me !!!
The document in the iframe can access its parent window via parent, and its parent window's document via parent.document. So:
parent.document.getElementById("texteditor").value = URL;
Note: To access each-other's documents, the main document and the iframe must be on the same origin. If they're on different origins, they can still communicate, but only if they both do so expressly, via web messaging.
Side note: Your iframe, as shown in the question, won't work. Inline content in iframes is for display when the browser doesn't support iframes. You use a separate resource (e.g., page) identified by the src attribute (or you use the srcdoc attribute; I have no idea how well supported it is), for the iframe's content.
E.g.:
Main page:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Main Page</title>
<body>
<textarea id="texteditor"></textarea>
<div class="mceeditor">
<iframe src="theframe.html"></iframe>
</div>
</body>
</html>
theframe.html:
<!doctype html>
<html>
<body>
<input type="button" value="Click to set" onclick="mySubmit()">
<script type="text/javascript">
function mySubmit() {
var URL = "http://localhost:61222/14CommunityImages/hands.png";
parent.document.getElementById("texteditor").value = URL;
}
</script>
</body>
</html>

First opportunity for document.body.appendChild

I am looking for the first opportunity to call document.body.appendChild to attach an element. I am currently using onload of body but as I understand it this waits until images and subframes load before triggering.
I require only that the solution work in IE (this is for an IE specific demo), but believe in the importance of giving cross-browser answers for other people to reference, so points if you give both.
Below is an illustration of what I am already doing.
<html>
<head>
<title>Insertion</title>
<script type="text/javascript">
function insertStuff() {
var iframe = document.createElement("iframe");
document.body.appendChild(iframe);
}
</script>
</head>
<body onload="insertStuff()">
</body>
</html>
<html>
<head>
<title>Insertion</title>
</head>
<body>
<script type="text/javascript">
function insertStuff() {
var iframe = document.createElement("iframe");
document.body.appendChild(iframe);
}
insertStuff()
</script>
<!-- Here goes all the other elements -->
</body>
</html>
This would be cross browser and work for IE6 and above for sure. Not sure about anything below that

Nested iframes, AKA Iframe Inception

Using jQuery I am trying to access div id="element".
<body>
<iframe id="uploads">
<iframe>
<div id="element">...</div>
</iframe>
</iframe>
</body>
All iframes are on the same domain with no www / non-www issues.
I have successfully selected elements within the first iframe but not the second nested iframe.
I have tried a few things, this is the most recent (and a pretty desperate attempt).
var iframe = jQuery('#upload').contents();
var iframeInner = jQuery(iframe).find('iframe').contents();
var iframeContent = jQuery(iframeInner).contents().find('#element');
// iframeContent is null
Edit:
To rule out a timing issue I used a click event and waited a while.
jQuery().click(function(){
var iframe = jQuery('#upload').contents().find('iframe');
console.log(iframe.find('#element')); // [] null
});
Any ideas?
Thanks.
Update:
I can select the second iframe like so...
var iframe = jQuery('#upload').contents().find('iframe');
The problem now seems to be that the src is empty as the iframe is generated with javascript.
So the iframe is selected but the content length is 0.
Thing is, the code you provided won't work because the <iframe> element has to have a "src" property, like:
<iframe id="uploads" src="http://domain/page.html"></iframe>
It's ok to use .contents() to get the content:
$('#uploads).contents() will give you access to the second iframe, but if that iframe is "INSIDE" the http://domain/page.html document the #uploads iframe loaded.
To test I'm right about this, I created 3 html files named main.html, iframe.html and noframe.html and then selected the div#element just fine with:
$('#uploads').contents().find('iframe').contents().find('#element');
There WILL be a delay in which the element will not be available since you need to wait for the iframe to load the resource. Also, all iframes have to be on the same domain.
Hope this helps ...
Here goes the html for the 3 files I used (replace the "src" attributes with your domain and url):
main.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>main.html example</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function () {
console.log( $('#uploads').contents().find('iframe').contents().find('#element') ); // nothing at first
setTimeout( function () {
console.log( $('#uploads').contents().find('iframe').contents().find('#element') ); // wait and you'll have it
}, 2000 );
});
</script>
</head>
<body>
<iframe id="uploads" src="http://192.168.1.70/test/iframe.html"></iframe>
</body>
iframe.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>iframe.html example</title>
</head>
<body>
<iframe src="http://192.168.1.70/test/noframe.html"></iframe>
</body>
noframe.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>noframe.html example</title>
</head>
<body>
<div id="element">some content</div>
</body>
var iframeInner = jQuery(iframe).find('iframe').contents();
var iframeContent = jQuery(iframeInner).contents().find('#element');
iframeInner contains elements from
<div id="element">other markup goes here</div>
and iframeContent will find for elements which are inside of
<div id="element">other markup goes here</div>
(find doesn't search on current element) that's why it is returning null.
Hey I got something that seems to be doing what you want a do. It involves some dirty copying but works. You can find the working code here
So here is the main html file :
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
Iframe = $('#frame1');
Iframe.on('load', function(){
IframeInner = Iframe.contents().find('iframe');
IframeInnerClone = IframeInner.clone();
IframeInnerClone.insertAfter($('#insertIframeAfter')).css({display:'none'});
IframeInnerClone.on('load', function(){
IframeContents = IframeInner.contents();
YourNestedEl = IframeContents.find('div');
$('<div>Yeepi! I can even insert stuff!</div>').insertAfter(YourNestedEl)
});
});
});
</script>
</head>
<body>
<div id="insertIframeAfter">Hello!!!!</div>
<iframe id="frame1" src="Test_Iframe.html">
</iframe>
</body>
</html>
As you can see, once the first Iframe is loaded, I get the second one and clone it. I then reinsert it in the dom, so I can get access to the onload event. Once this one is loaded, I retrieve the content from non-cloned one (must have loaded as well, since they use the same src). You can then do wathever you want with the content.
Here is the Test_Iframe.html file :
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>Test_Iframe</div>
<iframe src="Test_Iframe2.html">
</iframe>
</body>
</html>
and the Test_Iframe2.html file :
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>I am the second nested iframe</div>
</body>
</html>
You probably have a timing issue. Your document.ready commend is probably firing before the the second iFrame is loaded. You dont have enough info to help much further- but let us know if that seems like the possible issue.
You should use live method for elements which are rendered later, like colorbox, hidden fields or iframe
$(".inverter-value").live("change",function() {
elem = this
$.ajax({
url: '/main/invertor_attribute/',
type: 'POST',
aysnc: false,
data: {id: $(this).val() },
success: function(data){
// code
},
dataType: 'html'
});
});
I think the best way to reach your div:
var your_element=$('iframe#uploads').children('iframe').children('div#element');
It should work well.
If browser supports iframe, then DOM inside iframe come from src attribute of respective tag. Contents that are inside iframe tag are used as a fall back mechanism where browser does not supports iframe tag.
Ref: http://www.w3schools.com/tags/tag_iframe.asp
I guess your problem is that jQuery is not loaded in your iframes.
The safest approach is to rely on pure DOM-based methods to parse your content.
Or else, start with jQuery, and then once inside your iframes, test once if typeof window.jQuery == 'undefined', if it's true, jQuery is not enabled inside it and fallback on DOM-based method.

JavaScript: find dimensions of iframe body

I have a web page which embeds another page in an iframe. I want a JavaScript function in the outer document to fetch the size, in pixels, of the document in the iframe.
I have been exploring the DOM and the only attributes I can find relating to width and height give the height of the iframe itself, which is smaller than the document inside it.
e.g.
<iframe src="tall_page.php" id="my_iframe" style="height: 101px"></iframe>
...
var i = document .getElementById ("my_iframe");
i = i .contentDocument .body;
alert (i .offsetHeight); // or scrollHeight or clientHeight
The above will give "101". The value I am after is the size of the whole content document, not the frame -- and not just the <body>: if the CSS gives html{padding:x} for example, I want this to be inorporated.
How do I get this value?
Using jQuery this should work:
var height = $("my_iframe").height();
var width = $("my_iframe").width();
Hope that helps
I got it to work using the contentWindow object.
I think the idea here is to get the width/height of an
element that you set inside the iframe. In my example,
I set the iframe body to 3000px using css, and got it to work.
Keep in mind that since you're accessing an iframe's data,
you need to adhere to the same origin policy
Here is my example:
iframe.html
<!DOCTYPE html>
<html lang='en'>
<head>
<title>My Iframe</title>
</head>
<body id='mybody' style='width:3000px;'>
Hello!
</body>
</html>
index.html
<!DOCTYPE html>
<html lang='en'>
<head>
<title>My Test</title>
<script>
window.onload = function() {
var f = document.getElementById('myiframe');
console.dir(f.contentWindow.document.getElementById('mybody').clientWidth);
}
</script>
</head>
<body>
<iframe id='myiframe' src='iframe.html' height='480' width='640'>
</iframe>
</body>
</html>
Hope that helps.

JS: alert when clicking on a tag

i want to get alert when a A' tag inside the iframe is clicked , here is my code :
<Html>
<Head>
<Title>change links</Title>
</Head>
<body>
<iframe id="tab" src="http://www.site.com"></iframe>
<script type="text/javascript">
var tags = document.getElementsByTagName("a");
tags.addEventListener("click", alert(""), false);
</script>
</body>
</Html>
*the iframe isn't the same domain as where the script is running
why is't that working?
Becouse this is considered a Cross-Site request or also called XSS attack. It is strictly PROHIBITED to read or modify in any way the content of an iframe on a different domain.
Furthur more frames are deprecated in the new HTML5 standart, so using them is discouraged.

Categories

Resources