How to find specific element inside nested iframes - javascript

I need to find a specific element, which is inside an iframe, from a parent component, the structure would be something like this: (Just an example)
Edit: See comments below concerning the nature of this example
<iframe id ='if1'>
<iframe id ='if2'>
<iframe id ='if3'>
<iframe id ='if4'>
<input type='hidden' id ='elementToBeFound'>
</iframe>
</iframe>
</iframe>
</iframe>
Now, how can i do this with javascript? (Can also be jquery or another helper)
I have a reference to the first iframe ('if1'), i wanted to search all child nodes until i found 'elementToBeFound'.
Is this possible?
Thanks in advance.
My question is different from the existing ones, because i want to access multiple iframes inside iframes, not only one level.

I belive that something like this should work:
const elem = document.getElementById('if1').contentDocument
.getElementById('if2').contentDocument
.getElementById('if3').contentDocument
.getElementById('if4').contentDocument
.getElementById('elementToBeFound')
But for sure all windows should be loaded to do that. In real workld it may be more complicated you will need to listen for load event for each iframe to be able to check what is inside.

You can use this function to query for any element on the page, regardless of if it is nested inside of an iframe:
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.

You can get the div element by using iframe.contentWindow call.
Here is the example:
NOTE : You have to use "src" (external iframes) to make it work
<!DOCTYPE html>
<html>
<head>
<title>IF1</title>
</head>
<body>
<iframe id='if1' src="./iframe2.html">
<!-- <iframe id='if2'>
<iframe id='if3'>
<iframe id='if4'> -->
<!-- <div id='elementToFind'>Hello</div> -->
<!-- </iframe>
</iframe>
</iframe> -->
</iframe>
<script>
window.onload = function() {
let if1 = document.getElementById('if1').contentWindow;
let if2 = if1.document.getElementById('if2').contentWindow;
let div = if2.document.getElementById('elementToFind');
console.log(div)
}
</script>
</body>
</html>

Related

How to retrieve atributes from iframe?

I have an app which I am inserting another app using iframe as follows
Parent App
<HTML>
....
<body>
<iframe firstname="Trump" src="https://on.co/onboarding/" height="600" allowfullscreen="" >
</iframe>
</body>
</html>
Children App
<HTML>
....
<body>
<h1> Covid is deadly if you doubt ask the indians </h1>
<script>
const urlParams = new URLSearchParams(document.location.search);
const myParam = urlParams.get('firstname');
console.log(myParam) //undefined
</script>
</body>
</html>
I would like to get the first name from the iframe URL parameters
I get undefined
What is wrong here?
I think you just need:
<iframe src="https://on.co/onboarding/?firstname=SomeName" height="600" allowfullscreen=""></iframe>
It sounds like you're trying to get an element attribute, not a url parameter. You can get attributes using the getAttribute method on an element, e.g.
const myIframe = document.querySelector('iframe');
const firstname = myIframe?.getAttribute('firstname');
See https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute
Note however that the firstname attribute is useless on an iframe, so you should reconsider how you got it there in the first place.

One link opens two Iframe targets on same page

I currently have a working webpage that has a list of links that open in a targeted iFrame. I would like to add a subsequent iFrame target and be able to open supplementary pages in that iFrame as well as the original iFrame with the same link.
From my research, it seems this should be possible with some JS but I'm struggling to figure it out.
So basically, how could I click on "Lot 1" and open up a Youtube in the "gallery" iFrame and, say, www.example.com in the "info" iFrame simultaneously?
<iframe src="" name="gallery"</iframe>
<iframe src="" name="info"</iframe>
Lot 1
Lot 2
You can have an array/object storing the links, and then run an onclick event that will change the corresponding iframe sources to the values from said array (iframes have a src attribute which you can change through JS).
For example:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var frm = ['gallery', 'info'];
var hrf = ['http://example.com/', 'http://example.net/'];
function setSource() {
for(i=0, l=frm.length; i<l; i++) {
document.querySelector('iframe[name="'+frm[i]+'"]').src = hrf[i];
}
}
</script>
</head>
<body>
<iframe src="" name="gallery"></iframe>
<iframe src="" name="info"></iframe>
<span onclick="javascript: setSource();">Click me</span>
</body>
</html>
If you'd like to have multiple span elements, each changing the iframes' sources to a different set of links, you can always use a multidimensional array (an array of arrays) for src and add a parameter to the function:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var frm = ['gallery', 'info'];
var hrf = [['http://example0.com/', 'http://example0.net/'], ['http://example1.com/', 'http://example1.net/']];
function setSource(num) {
for(i=0, l=frm.length; i<l; i++) {
document.querySelector('iframe[name="'+frm[i]+'"]').src = hrf[num][i];
}
}
</script>
</head>
<body>
<iframe src="" name="gallery"></iframe>
<iframe src="" name="info"></iframe>
<span onclick="javascript: setSource(0);">Click me #0</span>
<span onclick="javascript: setSource(1);">Click me #1</span>
</body>
</html>
Here hrf is an array that contains another array (['http://example0.com/', 'http://example0.net/']) at index 0 and yet another one (['http://example1.com/', 'http://example1.net/']) - at index 1. By passing a parameter to setSource we can choose what subarray we want to pick to get the sources from.
Please don't forget to close your tags.
Using the a tag for your purpose is not a good idea, I recommend using a span. The a tag's purpose is to link the user to another document, not run javascript code (not using a also means you don't have to use preventDefault).
The javascript: prefix is used for the onclick attribute to provide backwards compatibility for some older mobile browsers.
This code works simply great :
<!DOCTYPE html>
<html>
<body>
<h1 style="display:flex;
justify-content:center;color:green;">
GeeksforGeeks
</h1>
<iframe src="about:blank" id="frame1"> </iframe>
<iframe src="about:blank" id="frame2"> </iframe>
<button id="update">Click me</button>
<script>
document.getElementById('update').addEventListener('click', function () {
// Change src attribute of iframes at a same time
document.getElementById('frame1').src ='https://www.google.com/search?q=java&igu=1';
document.getElementById('frame2').src ='https://www.google.com/search?q=farming&igu=1';
});
</script>
</body>
</html>

Use jQuery to Insert HTML into an iFrame Body Tag

I am using a hosted CMS that renders an iFrame within another iFrames. These iFrames are loaded from the same domain but since this is a hosted CMS I do not have access to these iFrames directly. Is it possible, using jQuery, to insert HTML content into the body tag of the iFrame with the id of re_contentIframe?
Here is how the code renders on my site:
<div class="editor">
<iframe id="editorf" frameborder="0" src="/ForumEditor.aspx?ForumID=2221&TopicID=-1&NoTemplate=False&Internal=False" style="display: inline;">
<html>
<head></head>
<body>
<!-- CODE -->
<iframe id="re_contentIframe" frameborder="0" src="javascript:'<html></html>';">
<html>
<head></head>
<body> <!-- THIS IS WHAT I WANT TO TARGET --> </body>
</html>
</iframe>
<!-- CODE -->
</body>
</html>
</iframe>
</div>
I tried using the following code but nothing happens with this code (including no errors):
$(function() {
$( "#test" ).click(function() {
$("#re_contentIframe").contents().find("body").html("<p>new HTML content goes here</p>");
});
});
The problem is that you are trying to access a nested frame.
The #re_contentIframe frame is nested within #editorf, which is subsequently nested within your document.
Try:
$('#re_contentIframe').contents().find('body').find('#editorf').contents()
Fiddle: http://jsfiddle.net/8VP4y/3/
haven't checked it ,might help :
var frameObject = document.getElementById('editorf');
var frameContent = frameObject.contentDocument ||
frameObject.contentWindow.document;
var insideIframe = frameContent.getElementById('re_contentIframe');
var insideIframeContent = insideIframeObject.contentDocument ||
insideIframeObject.contentWindow.document;
var $body = $('body',insideIframeContent);
$body.html('<div>contentupdated</div>');

iframe src to be massaged by javascript

To say that I am a novice in javascript is an insult to a novice. Even my limited HTML knowledge is self-taught. Here's my problem: I am trying to massage the src in a simple iframe, like so:
<html>
<head>
<script type="text/javascript">
function embedKey() {
var url = window.location.href;
var symbol = url.split('?')[1];
if(symbol=="INNO"){
uniqueKey = "&resid=27A14C5DE396792C%21235&authkey=ANDfOBKrOKskLqg"
return "https://skydrive.live.com/embed?cid=27A14C5DE396792C" + uniqueKey +"&em=2&wdAllowInteractivity=False&ActiveCell='Sheet1'!B3&wdHideGridlines=True&wdHideHeaders=True"
}
else {
alert(url);
return false;
}
}
</script>
</head>
<body>
<iframe width="402" height="346" frameborder="0" scrolling="no" src=javascript:embedKey();></iframe>
</body>
</html>
I will be adding many more conditions/symbols/return strings to the embedKey() function. Right now, I am trying to make it work with one.
I don't think JavaScript gets executed from a src attribute like that. With something like an href attribute on an a element (where one often sees inline JavaScript) there's at least a click event to respond to, but not in this case.
Instead of trying to call the function inline from the element like that, call it from a script block after the element has loaded. Something like this:
<iframe width="402" height="346" frameborder="0" scrolling="no" id="someIframe"></iframe>
<script type="text/javascript">
document.getElementById('someIframe').src = embedKey();
</script>

How to get parent iframe element from inner page without knowing id?

Let's imagine that I have something like this:
<html>
...
<div>
<iframe src="test.html" hash="r4d5f7"></iframe>
<iframe src="test.html" hash="8f7x97"></iframe>
<iframe src="test.html" hash="gg4v5e"></iframe>
<iframe src="test.html" hash="e54f87"></iframe>
</div>
...
</html>
test.html is empty page, custom hash attribute always has a different value, both pages are on the same domain for security reasons, number and order of iframe elements is random.
My question is: Is there a way to get from inner page (test.html) using Javascript to its proper iframe element? Let's say, I'm in the third iframe's page and I need to get to its iframe element and alert() hash value (in this case "gg4v5e").
To be more specific. If you are familiar with Firefox's Firebug, it visualizes this situation like this:
<html>
...
<div>
<iframe src="test.html" hash="r4d5f7">
<html>
...
</html>
</iframe>
<iframe src="test.html" hash="8f7x97">
<html>
...
</html>
</iframe>
<iframe src="test.html" hash="gg4v5e">
<html>
...
</html>
</iframe>
<iframe src="test.html" hash="e54f87">
<html>
...
</html>
</iframe>
</div>
...
</html>
Is it possible to call "something" in order to get parent element (<iframe>) when I'm with my Javascript at <html> element in inner page?
Sure there is.
This code works in FF and IE6, Opera, Chrome (requires a web server and both files coming from same domain protocol and port)
function getHash() {
var ifs = window.top.document.getElementsByTagName("iframe");
for(var i = 0, len = ifs.length; i < len; i++) {
var f = ifs[i];
var fDoc = f.contentDocument || f.contentWindow.document;
if(fDoc === document) {
alert(f.getAttribute("hash"));
}
}
}

Categories

Resources