Cannot get content of iframe - javascript

I am loading a local html document in an iframe, then trying to get access to its document from a script.
This is the javascript:
let ifrm = document.getElementById('iframeid');
console.log(ifrm);
let doc = ifrm.contentWindow.document;
console.log(doc);
This is the declaration of my iframe:
<iframe src="untitled.html" style="display:none" id="iframeid"></iframe>
This is the result:
As you can see, the content of the iframe disappears when I try to get the document. What am I doing wrong?

For some reason, you have to wait for the onload event.
Take a look here: http://plnkr.co/edit/fNEZLyWkjT952a7e3WNy?p=preview

Related

Append within Append, Iframe within Append in Jquery

I've looked at
Insert content into iFrame and their fiddle at http://jsfiddle.net/8VP4y/3/ to come out with the following codes which i'm having problem.
i've created a jsfiddle for my problem below.
https://jsfiddle.net/cy87j70t/2/
$( document ).ready(function() {
$('#card2').html( '<iframe id="myFrame"></iframe>' );
var myFrame = $("#myFrame").contents().find('body');
var myFrame2 = $("#myFrame2").contents().find('body');
myFrame.append('<p>OH NO TOKEN IS FOR myFrame Original ');
myFrame2.append('<p>OH NO TOKEN IS FOR myFrame 2 ');
});
AND the HTML looks like this;
<div id='card2'>
</div>
<iframe id='myFrame2'>
</iframe>
I'm trying to create a iframe using javascript, then writing to the iframe with content from JSONP (i've ommitted that part for easy debug);
I'm not sure why it's not writing to the iframe, is it because the iframe is created by javascript?
I've tried append, html, after, prepend but nothing seems to allow me to write to the iframe
No, it's not a bug.
Updated jsfiddle
The right way is:
$(function () {
$('#card2').html('<iframe id="myFrame"></iframe>');
// add the src attribute so that the load event will take place in every browser..
$("#myFrame").attr('src', 'about:blank');
// wait for the iframe is loaded
$("#myFrame").on('load', function(e) {
var myFrame = $("#myFrame").contents().find('body');
myFrame.append('<p>11111111OH NO TOKEN IS FOR myFrame Original</p>');
});
var myFrame2 = $("#myFrame2").contents().find('body');
myFrame2.append('<p>2222222222 OH NO TOKEN IS FOR myFrame 2</p>');
});
<script src="https://code.jquery.com/jquery-1.12.1.min.js"></script>
<div id='card2'>
</div>
<iframe id='myFrame2'>
</iframe>

`ImportNode` in Firefox and extracting an element from an `iframe`

I am trying to understand importNode in html using the following example.
Suppose we have a content.html:
<html>
<body>
<nav id="sidebar1" class="sidebar">
Hi there!
</nav>
</body>
</html>
and a main.html:
<html>
<body>
<iframe src='content.html' hidden='true'></iframe>
<script>
var idframe = document.getElementsByTagName("iframe")[0];
var oldNode = idframe.contentWindow.document.getElementsByTagName("nav")[0];
var newNode = document.importNode(oldNode, true);
document.getElementsByTagName("body")[0].appendChild(newNode);
alert("HI!!!");
</script>
</body>
</html>
I am getting the error:
TypeError: Argument 1 of Document.importNode is not an object.
var newNode = document.importNode(oldNode, true);
What is the proper way to get an element form an iframe and insert it into my html?
You can only access content of the iframe document after the iframe document has been loaded. This can be accomplished different ways:
either by putting your accessing code into load handler of the main (that contains iframe element) document window,
or inside a DOMContentLoaded event listener of the document loaded in iframe.
Below is example of using load event of window of the main document:
window.addEventListener('load', function() {
var iframe = document.getElementsByTagName("iframe")[0];
var oldNode = iframe.contentWindow.document.getElementById("myNode");
var newNode = document.importNode(oldNode, true);
document.body.insertBefore(newNode, document.body.firstChild);
}, false);
Otherwise, iframe content is not yet loaded when you try to access it.
See the live example at JSFiddle (iframe content is placed encoded in the srcdoc attribute of the iframe just because I'm not aware of ability to create subdocuments at JSFiddle without creating a separate fiddle).

How to store iframe in a variable?

<html>
<body>
<iframe id="src">
</body>
</html>
I want to have the iframe show up in the div element through a Javascript function but I can't seem to figure out what isn't working. Any ideas?
document.getElementById('site').src = http://www.w3schools.com/;
Thanks in advance!
Try
document.getElementById('src').src = 'http://www.w3schools.com/';
a) the url should be provided as string (quoted)
b) the id of your iframe is src not site
Your iframe don't have the id site, so your code won't have any effect.
(Also please note that you didn't close the iframe tag) .
Here's the right code (fiddle) .
<input type="button" onclick="changeIframeSrc('myFrame');" value="changeSrc">
<iframe src="http://www.example.com" id="myFrame"></iframe>
<script>
function changeIframeSrc(id) {
e = document.getElementById(id);
e.src = "http://www.wikipedia.com/";
}
</script>
First, a couple small things:
the id on your iframe appears to be src and not site; and
you need to close the iframe tag.
Assuming that you're just dealing with one iframe and it has an id then by all means:
var myIframe = document.getElementById('src');
// gives you just that one iframe element
You may want to consider document.querySelectorAll though, in case you're working with more than one iframe.
var iframes = document.querySelectorAll('iframe');
See that in action: http://jsbin.com/equzey/2/edit
And important side note: if all you need is access to the iframe element (e.g., to manipulate its source or to apply CSS via the style attribute) then the above should be fine. However, if you need to work with the contents of the iframe, you'll need to get inside its web page context with the contentWindow property:
var iframes = document.querySelectorAll('iframe');
iframes[0].contentWindow;

how to detect ,on load of the html document, whether the body of the iframe document is ready to be displayed?

Suppose a HTML document has a iframe.
Using javascript,I want to detect ,on load of the html document, whether the body of the iframe document is ready to be displayed.
I want to be able to overwrite the body contents (before it actullay loads) of the iframe.
Any suggestions? can I do it with jquery?
say if ,HTML doc is
<html>
<head>
</head>
<body>
<iframe id="ifrmId" src="http://www.google.com" >
</iframe>
</body>
</html>
You can use the onload event on the iframe element:
var iframe = document.getElementById('ifrmId');
iframe.onload = function () {
// iframe loaded
var innerDocument = iframe.contentDocument || iframe.contentWindow.document;
};
Edit: With jQuery, exactly the same idea:
$('#ifrmId').load(function () {
// iframe loaded
var innerDocument = $(this).contents();
});
Keep in mind that if you want to manipulate the iframe's inner document, the file needs to be on the same domain, this is because the same origin policy restrictions.

Unloading/Removing content from an iFrame

Is there anyway to unload a page that has been loaded inside an iframe? I do not want to change the iframe src to a blank page if possible. I am basically looking for something that will do something like this $('#frameID').attr("src",""); except that code does not seem to clear the previously loaded page.
Is there a "unload" function that I can call which will reset the iframe so that it does not have any content loaded inside?
The other solutions use innerHTML, which won't always work in XHTML. They also only clear document.body (anything in the <head> is still present). Here is a solution that uses the DOM:
var frame = document.getElementById("myFrame"),
frameDoc = frame.contentDocument || frame.contentWindow.document;
frameDoc.removeChild(frameDoc.documentElement);
This solution uses innerHTML:
var frame = document.getElementById("myFrame"),
frameDoc = frame.contentDocument || frame.contentWindow.document;
frameDoc.documentElement.innerHTML = "";
If you generate dynamically the content of your iframe, all scripts/variable loaded will leak from one write to another. Thus the solution provided by #Eli of clearing the dom element will not work.
In short:
To clean, wrap your iframe into a div element and replace its dom content.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div id="wrapper">
<iframe id="test"></iframe>
</div>
</body>
</html>
To clean:
var wrapper = document.getElementById('wrapper');
wrapper.innerHTML= "<iframe id='test'></iframe>";
In details: Demo of script leakage
Example of script leakage between two iframe writes (tested with Chrome):
var iframe = document.getElementById('test');
// define variable 'a'
var content = "<html><body><script>var a=555;</script></body></html>";
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(content);
iframe.contentWindow.document.close();
// uncomment this to clean the iframe
//document.getElementById('wrapper').innerHTML= "<iframe id='test'></iframe>";
// write 'a' if defined
var content2 = "<html><body><div id='content'></div><script>document.getElementById('content').innerHTML=typeof a === 'undefined' ? 'undefined' : a;</script></body></html>";
var iframe2 = document.getElementById('test');
iframe2.contentWindow.document.open();
iframe2.contentWindow.document.write(content2);
iframe2.contentWindow.document.close();
If you run this code, you will see the output of the second iframe is 555 although it has been defined in the first iframe.
If you uncomment the middle part it will work as expected.
Related question: Avoiding memory leaks loading content into an iframe
Try this,
$("iframe").contents().find("body").html('');
It only clears innerHTML of your tag inside and not actually unload your iframe so you can reuse your iframe without reloading it and its working in all browsers and quite simple!!
$('#frameID').contentWindow.document.body.innerHTML
= '';
As with any iframe, this only works if you're on the same domain.
var frame = document.getElementById("myframe");
frame.src = "about:blank";
This worked from me and prevented memory leaks too.
In my case I had to destroy the parent too. In that case you have to destroy the parent with some delay to prevent memory leak
Removing and recreating the iframe is the safest solution here.
By removing only the innerHTML of the iframe you don't flush the variables stored, the bound eventListeners etc.
Be careful with this, it might cause a lot of problems (like memory leaks, multiple triggers of the same event etc).
$("#frameId").contents().find("div#SomeDIVinsideFrame").remove(); // removes some div content inside iframe
$("#FrameId").remove(); // removes frame
had same problem to show iframe news on http://www.livepage.info
This worked for me, cleared everything within the iframe tag; body, head, html and all:
$("iframe").contents().empty();
If you had previously loaded content by setting the src property of the iframe, you cannot empty the content as it is a violation of cross site scripting.
You can then just set the src property to '' which will make the browser discard the whole content.
$('iframe').prop('src', '');
First, get the document of the frame:
var frame = $('#frameId').get(0);
var frameDoc = frame.contentDocument || frame.contentWindow.document;
Then, blank it:
frameDoc.getElementsByTagName('body')[0].innerHTML = "";
I think this should work too:
$('body', frameDoc).html("");
Now, you might want to do something with any scripts that might be loaded in the head, but this should get you started.
You can trigger unload event of that iframe like
$('body').trigger('unload');
and then remove the iframe from the parent window and reload a new iframe with new src when needed.
$('#iframe_wrapper').html('');
$('#iframe_wrapper').html('<iframe src="...">');
function getContentFromIframe(iFrameName)
{
var myIFrame = document.getElementById(iFrameName);
var content = myIFrame.contentWindow.document.body.innerHTML;
//Do whatever you need with the content
}
it will definitely work !!!!!!!!!!!!!!!!

Categories

Resources