Get element from within an iFrame - javascript

How do you get a <div> from within an <iframe>?

var iframe = document.getElementById('iframeId');
var innerDoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;
You could more simply write:
var iframe = document.getElementById('iframeId');
var innerDoc = iframe.contentDocument || iframe.contentWindow.document;
and the first valid inner doc will be returned.
Once you get the inner doc, you can just access its internals the same way as you would access any element on your current page. (innerDoc.getElementById...etc.)
IMPORTANT: Make sure that the iframe is on the same domain, otherwise you can't get access to its internals. That would be cross-site scripting. Reference:
MDN: <iframe> Scripting
MDN: Same-Origin Policy: Cross-Origin Script API Access

Do not forget to access iframe after it is loaded. Old but reliable way without jQuery:
<iframe src="samedomain.com/page.htm" id="iframe" onload="access()"></iframe>
<script>
function access() {
var iframe = document.getElementById("iframe");
var innerDoc = iframe.contentDocument || iframe.contentWindow.document;
console.log(innerDoc.body);
}
</script>

Above answers gave good solutions using Javscript.
Here is a simple jQuery solution:
$('#iframeId').contents().find('div')
The trick here is jQuery's .contents() method, unlike .children() which can only get HTML elements, .contents() can get both text nodes and HTML elements. That's why one can get document contents of an iframe by using it.
Further reading about jQuery .contents(): .contents()
Note that the iframe and page have to be on the same domain.

window.parent.document.getElementById("framekit").contentWindow.CallYourFunction('pass your value')
CallYourFunction() is function inside page and that function action on it

None of the other answers were working for me. I ended up creating a function within my iframe that returns the object I was looking for:
function getElementWithinIframe() {
return document.getElementById('copy-sheet-form');
}
Then you call that function like so to retrieve the element:
var el = document.getElementById("iframeId").contentWindow.functionNameToCall();

If iframe is not in the same domain such that you cannot get access to its internals from the parent but you can modify the source code of the iframe then you can modify the page displayed by the iframe to send messages to the parent window, which allows you to share information between the pages. Some sources:
https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
Html5 - Cross Browser Iframe postmessage - child to parent?
cross site iframe postMessage from child to parent

You can use this function to query for any element on the page, regardless of if it is nested inside of an iframe (or many iframes):
function querySelectorAllInIframes(selector) {
let elements = [];
const recurse = (contentWindow = window) => {
const iframes = contentWindow.document.body.querySelectorAll('iframe');
iframes.forEach(iframe => recurse(iframe.contentWindow));
elements = elements.concat(contentWindow.document.body.querySelectorAll(selector));
}
recurse();
return elements;
};
querySelectorAllInIframes('#elementToBeFound');
Note: Keep in mind that each of the iframes on the page will need to be of the same-origin, or this function will throw an error.

Below code will help you to find out iframe data.
let iframe = document.getElementById('frameId');
let innerDoc = iframe.contentDocument || iframe.contentWindow.document;

Related

Injecting html dom inside iframe's document and/or shadow-root

I am injecting iframe onto the webpage using javascript (using chrome extension). Using javascript, I am creating iframe and I can access my html's url, so I though I can fetch the DOM using $.get
var elt = document.createElement('iframe');
elt.id = 'my_iframe';
$.get(chrome.extension.getURL('views/test.html'), function(doc) {
var container = document.querySelector('#my_iframe');
console.log(container.documentContent); // can access
console.log(container.shadowRoot); // can't access
// ideally:
container.shadowRoot($(doc));
container.contentDocument($(doc));
});
document.getElementsByTagName('body')[0].appendChild(elt);
How can I inject my 'text.html' inside the #shadow-root?
The reason is that, when I use elt.src = url, it doesn't wrap the html content inside #document or #shadow-root, and this results in a bug - (blurry content in iframe when not wrapped in #document or #shadow-root - bug report)
If you are just changing the contents of an iframe, you can do it by:
const iframe = document.querySelector('#myIframe')
iframe.outerHTML = '<iframe></iframe>' // clears the iframe
iframe.contentDocument.open()
iframe.contentDocument.write(yourHTMLText)
iframe.contentDocument.close()

Removing all anchor title attributes in an iframe

Is there a way to remove all anchor title attributes in all links within an iframe so that when you hover over them you don't get the title?
I know I can do something like the following but for some reason it isn't working.
$("iframe").load(function() {
$("iframe").contents().find("a").each(function(index) {
$(this).attr('title','');
});
});
If iframe uses same protocol and domain, you can change iframe's content.
Different protocol or domain will generate an Security Exception.
This will work for you on the same domain:
$('iframe').load(function(){
$(this).contents().find('a').removeAttr('title');
})
If you are not on the same domain, it will not work. See the following SO Question/Answer:
Get DOM content of cross-domain iframe
Given the contents of iFrame is from same domain you can use the following for every anchor tag
$('a').removeAttr('title');
Try This:
Javascript: Demo
var iframe = document.getElementById('iframeId');
var innerDoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;
var links = innerDoc.getElementsByTagName("a");
for (var i = 0; i < links.length; i++) {
links[i].removeAttribute("title");
}
Jquery: Demo
setTimeout( function () {
$("#iframeId").contents().find("a").removeAttr("title");
}, 1000 );

How to traverse an HTML document loaded using iframe? [duplicate]

<iframe id="id_description_iframe" class="rte-zone" height="200" frameborder="0" title="description">
<html>
<head></head>
<body class="frameBody">
test<br/>
</body>
</html>
</iframe>
What I want to get is:
test<br/>
The exact question is how to do it with pure JavaScript not with jQuery.
But I always use the solution that can be found in jQuery's source code.
It's just one line of native JavaScript.
For me it's the best, easy readable and even afaik the shortest way to get the iframes content.
First get your iframe
var iframe = document.getElementById('id_description_iframe');
// or
var iframe = document.querySelector('#id_description_iframe');
And then use jQuery's solution
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
It works even in the Internet Explorer which does this trick during the contentWindow property of the iframe object. Most other browsers uses the contentDocument property and that is the reason why we proof this property first in this OR condition. If it is not set try contentWindow.document.
Select elements in iframe
Then you can usually use getElementById() or even querySelectorAll() to select the DOM-Element from the iframeDocument:
if (!iframeDocument) {
throw "iframe couldn't be found in DOM.";
}
var iframeContent = iframeDocument.getElementById('frameBody');
// or
var iframeContent = iframeDocument.querySelectorAll('#frameBody');
Call functions in the iframe
Get just the window element from iframe to call some global functions, variables or whole libraries (e.g. jQuery):
var iframeWindow = iframe.contentWindow;
// you can even call jQuery or other frameworks
// if it is loaded inside the iframe
iframeContent = iframeWindow.jQuery('#frameBody');
// or
iframeContent = iframeWindow.$('#frameBody');
// or even use any other global variable
iframeWindow.myVar = window.myVar;
// or call a global function
var myVar = iframeWindow.myFunction(param1 /*, ... */);
Note
All this is possible if you observe the same-origin policy.
Using JQuery, try this:
$("#id_description_iframe").contents().find("body").html()
it works perfectly for me :
document.getElementById('iframe_id').contentWindow.document.body.innerHTML;
AFAIK, an Iframe cannot be used that way. You need to point its src attribute to another page.
Here's how to get its body content using plane old javascript. This works with both IE and Firefox.
function getFrameContents(){
var iFrame = document.getElementById('id_description_iframe');
var iFrameBody;
if ( iFrame.contentDocument )
{ // FF
iFrameBody = iFrame.contentDocument.getElementsByTagName('body')[0];
}
else if ( iFrame.contentWindow )
{ // IE
iFrameBody = iFrame.contentWindow.document.getElementsByTagName('body')[0];
}
alert(iFrameBody.innerHTML);
}
use content in iframe with JS:
document.getElementById('id_iframe').contentWindow.document.write('content');
I think placing text inbetween the tags is reserved for browsers that cant handle iframes i.e...
<iframe src ="html_intro.asp" width="100%" height="300">
<p>Your browser does not support iframes.</p>
</iframe>
You use the 'src' attribute to set the source of the iframes html...
Hope that helps :)
Chalkey is correct, you need to use the src attribute to specify the page to be contained in the iframe. Providing you do this, and the document in the iframe is in the same domain as the parent document, you can use this:
var e = document.getElementById("id_description_iframe");
if(e != null) {
alert(e.contentWindow.document.body.innerHTML);
}
Obviously you can then do something useful with the contents instead of just putting them in an alert.
The following code is cross-browser compliant. It works in IE7, IE8, Fx 3, Safari, and Chrome, so no need to handle cross-browser issues. Did not test in IE6.
<iframe id="iframeId" name="iframeId">...</iframe>
<script type="text/javascript">
var iframeDoc;
if (window.frames && window.frames.iframeId &&
(iframeDoc = window.frames.iframeId.document)) {
var iframeBody = iframeDoc.body;
var ifromContent = iframeBody.innerHTML;
}
</script>
To get body content from javascript ,i have tried the following code:
var frameObj = document.getElementById('id_description_iframe');
var frameContent = frameObj.contentWindow.document.body.innerHTML;
where "id_description_iframe" is your iframe's id.
This code is working fine for me.
If you want to not just select the body of your iframe, but also insert some content to it, and do that with pure JS, and with no JQuery, and without document.write(), I have a solution that no other answer provides.
You can use the following steps
1.Select your iframe:
var iframe = document.getElementById("adblock_iframe");
2.Create an element that you want to insert into the frame, let's say an image:
var img = document.createElement('img');
img.src = "https://server-name.com/upload/adblock" + id + ".jpg";
img.style.paddingLeft = "450px";
//scale down the image is we have a high resolution screen on the client side
if (retina_test_media == true && high_res_test == true) {
img.style.width = "200px";
img.style.height = "50px";
} else {
img.style.width = "400px";
img.style.height = "100px";
}
img.id = "image";
3.Insert the image element into the iframe:
iframe.contentWindow.document.body.appendChild(img);
You can get the contents of the iframe body in one line of code:
document.getElementsByTagName('iframe')[0].contentWindow.document.body.innerText;

Filling an IFRAME with dynamic content from JavaScript

I have an IFRAME that should be filled with content from JavaScript. Had the content be on the server all I had to do is:
function onIFrameFill() {
myIframe.location.href = "HelloWorld.html";
}
But the content I have is a HTML page generated on the client and represented as a string (I have not much influence on it). How can I populate the content of the my iframe programatically?
I think you're looking for something like:
var iframeDoc = myIframe.contentWindow.document;
iframeDoc.open();
iframeDoc.write('hello world');
iframeDoc.close();
Tried setting .innerHTML but that does not work. Solution by Jeffery To works. Just want to add that myIframe.contentWindow might not work in old browsers (read IE old versions) so you can do
var iFrameWindow = myIframe.contentWindow || myIframe.documentWindow;
var iFrameDoc = iFrameWindow.document;
then use the document open(), write() & close() as above.
What about .innerHTML?
myIframe.innerHTML = "This is some HTML <b>text</b>";
Similar to Jeffry but using contentDocument instead.
let iframe = document.querySelector('iframe');
let doc = iframe.contentDocument;
doc.open();
doc.write('Hello world!');
doc.close();

How to get the body's content of an iframe in Javascript?

<iframe id="id_description_iframe" class="rte-zone" height="200" frameborder="0" title="description">
<html>
<head></head>
<body class="frameBody">
test<br/>
</body>
</html>
</iframe>
What I want to get is:
test<br/>
The exact question is how to do it with pure JavaScript not with jQuery.
But I always use the solution that can be found in jQuery's source code.
It's just one line of native JavaScript.
For me it's the best, easy readable and even afaik the shortest way to get the iframes content.
First get your iframe
var iframe = document.getElementById('id_description_iframe');
// or
var iframe = document.querySelector('#id_description_iframe');
And then use jQuery's solution
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
It works even in the Internet Explorer which does this trick during the contentWindow property of the iframe object. Most other browsers uses the contentDocument property and that is the reason why we proof this property first in this OR condition. If it is not set try contentWindow.document.
Select elements in iframe
Then you can usually use getElementById() or even querySelectorAll() to select the DOM-Element from the iframeDocument:
if (!iframeDocument) {
throw "iframe couldn't be found in DOM.";
}
var iframeContent = iframeDocument.getElementById('frameBody');
// or
var iframeContent = iframeDocument.querySelectorAll('#frameBody');
Call functions in the iframe
Get just the window element from iframe to call some global functions, variables or whole libraries (e.g. jQuery):
var iframeWindow = iframe.contentWindow;
// you can even call jQuery or other frameworks
// if it is loaded inside the iframe
iframeContent = iframeWindow.jQuery('#frameBody');
// or
iframeContent = iframeWindow.$('#frameBody');
// or even use any other global variable
iframeWindow.myVar = window.myVar;
// or call a global function
var myVar = iframeWindow.myFunction(param1 /*, ... */);
Note
All this is possible if you observe the same-origin policy.
Using JQuery, try this:
$("#id_description_iframe").contents().find("body").html()
it works perfectly for me :
document.getElementById('iframe_id').contentWindow.document.body.innerHTML;
AFAIK, an Iframe cannot be used that way. You need to point its src attribute to another page.
Here's how to get its body content using plane old javascript. This works with both IE and Firefox.
function getFrameContents(){
var iFrame = document.getElementById('id_description_iframe');
var iFrameBody;
if ( iFrame.contentDocument )
{ // FF
iFrameBody = iFrame.contentDocument.getElementsByTagName('body')[0];
}
else if ( iFrame.contentWindow )
{ // IE
iFrameBody = iFrame.contentWindow.document.getElementsByTagName('body')[0];
}
alert(iFrameBody.innerHTML);
}
use content in iframe with JS:
document.getElementById('id_iframe').contentWindow.document.write('content');
I think placing text inbetween the tags is reserved for browsers that cant handle iframes i.e...
<iframe src ="html_intro.asp" width="100%" height="300">
<p>Your browser does not support iframes.</p>
</iframe>
You use the 'src' attribute to set the source of the iframes html...
Hope that helps :)
Chalkey is correct, you need to use the src attribute to specify the page to be contained in the iframe. Providing you do this, and the document in the iframe is in the same domain as the parent document, you can use this:
var e = document.getElementById("id_description_iframe");
if(e != null) {
alert(e.contentWindow.document.body.innerHTML);
}
Obviously you can then do something useful with the contents instead of just putting them in an alert.
The following code is cross-browser compliant. It works in IE7, IE8, Fx 3, Safari, and Chrome, so no need to handle cross-browser issues. Did not test in IE6.
<iframe id="iframeId" name="iframeId">...</iframe>
<script type="text/javascript">
var iframeDoc;
if (window.frames && window.frames.iframeId &&
(iframeDoc = window.frames.iframeId.document)) {
var iframeBody = iframeDoc.body;
var ifromContent = iframeBody.innerHTML;
}
</script>
To get body content from javascript ,i have tried the following code:
var frameObj = document.getElementById('id_description_iframe');
var frameContent = frameObj.contentWindow.document.body.innerHTML;
where "id_description_iframe" is your iframe's id.
This code is working fine for me.
If you want to not just select the body of your iframe, but also insert some content to it, and do that with pure JS, and with no JQuery, and without document.write(), I have a solution that no other answer provides.
You can use the following steps
1.Select your iframe:
var iframe = document.getElementById("adblock_iframe");
2.Create an element that you want to insert into the frame, let's say an image:
var img = document.createElement('img');
img.src = "https://server-name.com/upload/adblock" + id + ".jpg";
img.style.paddingLeft = "450px";
//scale down the image is we have a high resolution screen on the client side
if (retina_test_media == true && high_res_test == true) {
img.style.width = "200px";
img.style.height = "50px";
} else {
img.style.width = "400px";
img.style.height = "100px";
}
img.id = "image";
3.Insert the image element into the iframe:
iframe.contentWindow.document.body.appendChild(img);
You can get the contents of the iframe body in one line of code:
document.getElementsByTagName('iframe')[0].contentWindow.document.body.innerText;

Categories