0

I found many related questions but none of them had a solution that worked for me, so apologies if this is a dupe.

I have the following HTML structure (simplified) :

<html>
<head>
</head>
<body style="">
    <div>
        <div>
            <div>
                <iframe>
                    <html>
                        <head></head>
                        <body>
                            <div></div>
                            <iframe>
                                <html>
                                    <head></head>
                                    <body>
                                        <div>
                                            <iframe src="about:blank">
                                                <html>
                                                    <head></head>
                                                    <body>
                                                        <img />
                                                        <iframe id="some_random_id">
                                                            <html>
                                                                <head></head>
                                                                <body>
                                                                    <div>
                                                                        <!-- main content -->
                                                                    </div>
                                                                </body>
                                                            </html>
                                                        </iframe>
                                                    </body>
                                                </html>
                                            </iframe>
                                        </div>
                                    </body>
                                </html>
                            </iframe>
                        </body>
                    </html>
                </iframe>
            </div>
        </div>
    </div>
</body>
</html>

And I would like to retrieve all the iframes, ideally in an array. I have tried the following:

document.getElementsByTagName('iframe')

But that returns an array of size 1 : [iframe]

window.frames.length give me 1

I thought about doing something like :

var a = document.getElementsByTagName('iframe')[0]
var b = a.getElementsByTagName('iframe')[0] 
// b is undefined
var b = a.contentDocument.getElementsByTagName('iframe')[0]
// b is undefined

Is there any way to retrieve all iframe on the page? Alternatively, just getting the last one (the one with the id some_random_id) would works as fine, but I can't use the id to select it since the html is created by a third party.

Edit: I don't think my question is a duplicate of using document.getElementsByTagName on a page with iFrames - elements inside the iframe are not being picked up because the accepted answer in this question use:

for( j=0; j<m; j++) {
    ...
} 

Where m is document.getElementsByTagName('iframe').length. But in my case it would have the value 1 and thus I couldn't access the nested iframes.

Bharata
  • 13,509
  • 6
  • 36
  • 50
L. Faros
  • 1,754
  • 3
  • 16
  • 35
  • Possible duplicate of [using document.getElementsByTagName on a page with iFrames - elements inside the iframe are not being picked up](https://stackoverflow.com/questions/11144479/using-document-getelementsbytagname-on-a-page-with-iframes-elements-inside-the) – Muhammet Can TONBUL Nov 08 '18 at 11:40
  • You can only do this if all the iframes are from same domain. Is that true? – charlietfl Nov 08 '18 at 11:41
  • None of the iframe have a domain except for the one with ` src="about:blank"` but I don't think ` about:blank` is a domain right ? – L. Faros Nov 08 '18 at 11:42
  • 1
    OK. Then you need to get inside each content window first before using `getElementsByTagName`. Every iframe has it's own `window` which is different than it's parent window – charlietfl Nov 08 '18 at 11:49
  • Not sure on how to do that, isn't it what I tried in the last code snippet I put ? (the one before the Edit) – L. Faros Nov 08 '18 at 11:53

1 Answers1

0

You are using the <iframe> tag absolutely wrong! You would like to read the documentation from <iframe> tag:

Permitted content: Fallback content, i.e. content that is normally not rendered, but that browsers not supporting the <iframe> element will render.

In other words the content between <iframe> and </iframe> tags will be rendered, if the browser do not support the <iframe> element.

You have two possibilities to use <iframe> tag:

  1. In the src attribute from <iframe> tag you could write a path to HTML file.
  2. In the src attribute from <iframe> tag you could write "about:blank" and then using JS you could add the content to this <iframe>.

If you want find some elements or manipulate the content from this iframes you could use the following code:

var iframe = document.getElementById('iframeId'),
    innerDoc = iframe.contentDocument ? iframe.contentDocument 
             : iframe.contentWindow.document;

You should be sure that you have an access to your <iframe>.
Please read Cross-origin resource sharing (CORS) article about it.

If you want to get the count of all nested iframes on document you have to find it for each <iframe> separatelly and to add this count to your global iframe count variable. And do not forget about the CORS (see above).

Bharata
  • 13,509
  • 6
  • 36
  • 50
  • CORS doesn't help with iframes. – Quentin Nov 08 '18 at 16:39
  • Well as I said in the question I can't use the `document.getElementById` because the id is random. And FYI the DOM structure I posted is the simplified version of what some js third party insert in one of my pages, I needed to get access to the html in the most nested iframe. Anyway I went with the method suggested by charlietfl in comments which is working – L. Faros Nov 08 '18 at 16:40
  • @L.Faros if you read my answer again then you will see that I wrote the same like `charlietfl` in his comments: 1. CORS (same domain). 2. `iframe.contentDocument` or `iframe.contentWindow.document`. My answer is detailed – so each user could understand it. And if this works, then you could mark my answer as accepted, please. – Bharata Nov 08 '18 at 17:05