I have small snippet that is inside iframe and generates script html tag and appends it to the window.top.document.head.
Now I want to know how do I check from within potato.js from which iframe it was generated from once it is already loaded?
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<iframe>
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script>
(function() {
var s = document.createElement('script');
s.setAttribute('type','text/javascript');
s.setAttribute('src','https://test.com/potato.js');
window.top.document.head.appendChild(s);
})();
</script>
</body>
</html>
</iframe>
</body>
</html>
Edit: I can not change this code inside the iframe
That information isn't stored automatically.
The only way I can think of would be to add an expando-prop to the script with a reference to the current window (i.e. the frame's window)…
s.sourceWindow = window;
… then read that from within potato.js …
const sourceWindow = document.currentScript.sourceWindow;
… and then loop over all the frames (window.frames) looking for a match.
Since you are using window.top and not window.parent you might need to be recursive there.
I have a very simple setup on a dev server (both pages are on my local test server localhost:5500) where I have a main page
<!DOCTYPE html>
<html lang="en">
<head>
<title>Example Mockup</title>
</head>
<body>
<iframe src="./nested.html" id="frame"></iframe>
<script>
var iframe = document.getElementById('frame');
console.log(iframe.contentDocument.body);
</script>
</body>
</html>
and a nested page
<html>
<body>
<div id="hello">Hello, World</div>
</body>
</html>
when I load the main page in my browser the output written to console is: <body></body>
I can access the element #hello using iframe.contentDocument.getElementById('hello') but I want the body element including child elements. Can anyone please explain to me why is this happening
You have to wait until iframe loaded completely to access it's body.
var iframe = document.getElementById('frame');
iframe.onload = function () {
console.log(iframe.contentDocument.body);
}
I have a html file which contains iframe like below lines of code. Note that this iframe is displayed by one of tiny mce jquery and is rendered in browser as
below
<html>
<body>
<textarea id="texteditor"></textarea>
<div class="mceeditor">
<iframe>
<html>
<body>
<script type="text/javascript">
function mySubmit() {
var URL = "http://localhost:61222/14CommunityImages/hands.png";
window.document.getElementById("texteditor").value = URL;
}
</script>
</body>
</html>
</iframe>
</div>
</body>
</html>
Now my goal is to append var url inside text area which is in parent html tag.
Please help me !!!
The document in the iframe can access its parent window via parent, and its parent window's document via parent.document. So:
parent.document.getElementById("texteditor").value = URL;
Note: To access each-other's documents, the main document and the iframe must be on the same origin. If they're on different origins, they can still communicate, but only if they both do so expressly, via web messaging.
Side note: Your iframe, as shown in the question, won't work. Inline content in iframes is for display when the browser doesn't support iframes. You use a separate resource (e.g., page) identified by the src attribute (or you use the srcdoc attribute; I have no idea how well supported it is), for the iframe's content.
E.g.:
Main page:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Main Page</title>
<body>
<textarea id="texteditor"></textarea>
<div class="mceeditor">
<iframe src="theframe.html"></iframe>
</div>
</body>
</html>
theframe.html:
<!doctype html>
<html>
<body>
<input type="button" value="Click to set" onclick="mySubmit()">
<script type="text/javascript">
function mySubmit() {
var URL = "http://localhost:61222/14CommunityImages/hands.png";
parent.document.getElementById("texteditor").value = URL;
}
</script>
</body>
</html>
Using jQuery I am trying to access div id="element".
<body>
<iframe id="uploads">
<iframe>
<div id="element">...</div>
</iframe>
</iframe>
</body>
All iframes are on the same domain with no www / non-www issues.
I have successfully selected elements within the first iframe but not the second nested iframe.
I have tried a few things, this is the most recent (and a pretty desperate attempt).
var iframe = jQuery('#upload').contents();
var iframeInner = jQuery(iframe).find('iframe').contents();
var iframeContent = jQuery(iframeInner).contents().find('#element');
// iframeContent is null
Edit:
To rule out a timing issue I used a click event and waited a while.
jQuery().click(function(){
var iframe = jQuery('#upload').contents().find('iframe');
console.log(iframe.find('#element')); // [] null
});
Any ideas?
Thanks.
Update:
I can select the second iframe like so...
var iframe = jQuery('#upload').contents().find('iframe');
The problem now seems to be that the src is empty as the iframe is generated with javascript.
So the iframe is selected but the content length is 0.
Thing is, the code you provided won't work because the <iframe> element has to have a "src" property, like:
<iframe id="uploads" src="http://domain/page.html"></iframe>
It's ok to use .contents() to get the content:
$('#uploads).contents() will give you access to the second iframe, but if that iframe is "INSIDE" the http://domain/page.html document the #uploads iframe loaded.
To test I'm right about this, I created 3 html files named main.html, iframe.html and noframe.html and then selected the div#element just fine with:
$('#uploads').contents().find('iframe').contents().find('#element');
There WILL be a delay in which the element will not be available since you need to wait for the iframe to load the resource. Also, all iframes have to be on the same domain.
Hope this helps ...
Here goes the html for the 3 files I used (replace the "src" attributes with your domain and url):
main.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>main.html example</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function () {
console.log( $('#uploads').contents().find('iframe').contents().find('#element') ); // nothing at first
setTimeout( function () {
console.log( $('#uploads').contents().find('iframe').contents().find('#element') ); // wait and you'll have it
}, 2000 );
});
</script>
</head>
<body>
<iframe id="uploads" src="http://192.168.1.70/test/iframe.html"></iframe>
</body>
iframe.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>iframe.html example</title>
</head>
<body>
<iframe src="http://192.168.1.70/test/noframe.html"></iframe>
</body>
noframe.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>noframe.html example</title>
</head>
<body>
<div id="element">some content</div>
</body>
var iframeInner = jQuery(iframe).find('iframe').contents();
var iframeContent = jQuery(iframeInner).contents().find('#element');
iframeInner contains elements from
<div id="element">other markup goes here</div>
and iframeContent will find for elements which are inside of
<div id="element">other markup goes here</div>
(find doesn't search on current element) that's why it is returning null.
Hey I got something that seems to be doing what you want a do. It involves some dirty copying but works. You can find the working code here
So here is the main html file :
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
Iframe = $('#frame1');
Iframe.on('load', function(){
IframeInner = Iframe.contents().find('iframe');
IframeInnerClone = IframeInner.clone();
IframeInnerClone.insertAfter($('#insertIframeAfter')).css({display:'none'});
IframeInnerClone.on('load', function(){
IframeContents = IframeInner.contents();
YourNestedEl = IframeContents.find('div');
$('<div>Yeepi! I can even insert stuff!</div>').insertAfter(YourNestedEl)
});
});
});
</script>
</head>
<body>
<div id="insertIframeAfter">Hello!!!!</div>
<iframe id="frame1" src="Test_Iframe.html">
</iframe>
</body>
</html>
As you can see, once the first Iframe is loaded, I get the second one and clone it. I then reinsert it in the dom, so I can get access to the onload event. Once this one is loaded, I retrieve the content from non-cloned one (must have loaded as well, since they use the same src). You can then do wathever you want with the content.
Here is the Test_Iframe.html file :
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>Test_Iframe</div>
<iframe src="Test_Iframe2.html">
</iframe>
</body>
</html>
and the Test_Iframe2.html file :
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>I am the second nested iframe</div>
</body>
</html>
You probably have a timing issue. Your document.ready commend is probably firing before the the second iFrame is loaded. You dont have enough info to help much further- but let us know if that seems like the possible issue.
You should use live method for elements which are rendered later, like colorbox, hidden fields or iframe
$(".inverter-value").live("change",function() {
elem = this
$.ajax({
url: '/main/invertor_attribute/',
type: 'POST',
aysnc: false,
data: {id: $(this).val() },
success: function(data){
// code
},
dataType: 'html'
});
});
I think the best way to reach your div:
var your_element=$('iframe#uploads').children('iframe').children('div#element');
It should work well.
If browser supports iframe, then DOM inside iframe come from src attribute of respective tag. Contents that are inside iframe tag are used as a fall back mechanism where browser does not supports iframe tag.
Ref: http://www.w3schools.com/tags/tag_iframe.asp
I guess your problem is that jQuery is not loaded in your iframes.
The safest approach is to rely on pure DOM-based methods to parse your content.
Or else, start with jQuery, and then once inside your iframes, test once if typeof window.jQuery == 'undefined', if it's true, jQuery is not enabled inside it and fallback on DOM-based method.
I have a textarea in which I wan't to add HTML code that will compose a full webpage, and as I type this content will be rendered in an iframe
For example in the textarea I'll write the following code:
<!DOCTYPE html>
<html>
<head>
<title>Live generate</title>
<style></style>
</head>
<body>
</body>
</html>
My problem is that I don't know how to access the iFrame in order to change it's full content so that it matches the one above
you should be able to get the iframe by its id with document.getElementsById or through jquery and then get its document, open it and write to it.
Like:
var iframe = $("iframe"); // or by Id $("#myIframeId")
var doc = iframe.document;
doc.open();
doc.write($("#myTextArea").text());
doc.close();