308

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

joepour
  • 6,831
  • 10
  • 32
  • 29

7 Answers7

477
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:

starball
  • 20,030
  • 7
  • 43
  • 238
geowa4
  • 40,390
  • 17
  • 88
  • 107
  • 6
    Great answer. Did you know that you can do: var innerDoc = iframe.contentDocument || iframe.contentWindow.document; //more readable and means the same – David Snabel-Caunt Jul 06 '09 at 18:40
  • 5
    I've seen people confused by that more than ternary operators. They seem to not know that the first valid one is returned. – geowa4 Jul 06 '09 at 18:44
  • 6
    in fact, as i edited the answer to include it, the guy over my shoulder asked me what that did... – geowa4 Jul 06 '09 at 18:46
  • 15
    Probably better to educate than use more complex code for simplicity :) – David Snabel-Caunt Jul 07 '09 at 11:28
  • I know and found the above answer is correct, but while doing innerDoc.getElementById("idab") I got an error like "Error: Permission denied to access property 'getElementById'". Do you know why this error came. – Deepak Lamichhane Dec 19 '11 at 01:15
  • I also get an error (in Chrome) when trying to access an Element in an iframe whose domain differs from the top page. Any way around this? – JellicleCat Aug 08 '12 at 23:06
  • 1
    @JellicleCat: Any way around that is a way to do "Cross-site request forgery", also known as "one-click" attack or "session riding" – M. Jahedbozorgan Jan 10 '13 at 18:57
  • sometimes trying to get the content of the iframe returns null, be sure to check for that. – Udo Feb 24 '16 at 03:24
  • While this may error out on a hosted page, running a local file in the browser with this code worked, at least on Safari and a publicly shared printer's web server. – cde Aug 10 '16 at 06:18
  • What's the difference between `iframe.contentDocument` and `iframe.contentWindow.document`? – Stevoisiak Jul 12 '18 at 19:14
  • @StevenM.Vascellaro Cross browser – Rahil Wazir May 24 '19 at 11:15
  • Is it possible to do cross-site scripting?? i wanna do a scrapper... – MonneratRJ Dec 02 '20 at 05:03
  • 4
    Is there a way to get access to the iframe internals if the iframe originates from a different URL. You mentioned that it is cross-site scripting, but I am wondering if there is a way. – Fabian Amran Jan 06 '22 at 06:12
  • @FabianAmran If there was a way all PHP applications that use hidden input fields for csrf tokens would be hacked to the ground by now – Seangle Feb 22 '23 at 11:22
21

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>
lukyer
  • 7,595
  • 3
  • 37
  • 31
11

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.

Community
  • 1
  • 1
Lying_cat
  • 1,288
  • 2
  • 12
  • 16
6
window.parent.document.getElementById("framekit").contentWindow.CallYourFunction('pass your value')

CallYourFunction() is function inside page and that function action on it

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
VishalDream
  • 311
  • 3
  • 6
1

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();
craned
  • 2,991
  • 2
  • 34
  • 38
0

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:

Jose V
  • 1,655
  • 1
  • 17
  • 31
0

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.

Cary Meskell
  • 312
  • 2
  • 10