Access DOM from iFrame - javascript

I have inserted a HTML page into an iframe:
<iframe src="file:///C:/editor.html" width="1000" height="500" frameborder="0"></iframe>
Now I need to access to the DOM from the iframe and get an element by id.
This is my editor.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Diagram</title>
<script type="text/javascript" src="lib/jquery-1.8.1.js"></script>
<!-- I use many resources -->
<script>
function generatePNG (oViewer) {
var oImageOptions = {
includeDecoratorLayers: false,
replaceImageURL: true
};
var d = new Date();
var h = d.getHours();
var m = d.getMinutes();
var s = d.getSeconds();
var sFileName = "diagram" + h.toString() + m.toString() + s.toString() + ".png";
var sResultBlob = oViewer.generateImageBlob(function(sBlob) {
b = 64;
var reader = new window.FileReader();
reader.readAsDataURL(sBlob);
reader.onloadend = function() {
base64data = reader.result;
var image = document.createElement('img');
image.setAttribute("id", "GraphImage");
image.src = base64data;
document.body.appendChild(image);
}
}, "image/png", oImageOptions);
return sResult;
}
</script>
</head>
<body >
<div id="diagramContainer"></div>
</body>
</html>
I need to access the DOM from the iframe, and get image.src from my edtior.html. How can I do this?

Use window.parent or window.top to access the parent/primary frame window. Then you can get their elements with
window.parent.document.getElementById("id")
and so on.
So you can have in iframe.html:
<html><body>
<script>
var getDiv = function(){
return window.parent.document.getElementById("test");
}
</script>
</body></html>
And a page containing it:
<html><body>
<div id="test"></div>
<iframe src="#####/iframe.html"></iframe>
</html></body>
Now calling getDiv() inside the iframe will fetch you the div[id=test] inside the parent frame.
If you want to do the opposite, i.e. access an element inside an iframe from outside the iframe, please read this answer:
Javascript - Get element from within an iFrame

Related

Javascript and Frame

The following code keeps showing a blank page.
I tried 2 different ways.
It seems that either the function doesn't get called or that the frame doesn't get updated.
What is wrong?
Thx.
<html>
<head>
<script type="text/javascript">
var links = [];
links[0] = "http://www.cbs.com";
links[1] = "http://www.nbc.com";
links[2] = "http://www.cnn.com";
var x = 0;
var delay = 3000;
changeLink();
function changeLink()
{
document.getElementById("report").source = links[x];
// parent.report.location = links[x];
x = x + 1;
if( x > 2) { x = 0;}
setTimeout(function() { changeLink() }, delay);
}
</script>
<title>Report</title>
<body>
<frameset border="0" frameborder="0">
<frame name="report" id="report" src="#" frameborder="0" scrolling="no">
</frameset>
</body>
</head>
</html>
change this line
document.getElementById("report").source = links[x];
to
document.getElementById("report").src = links[x];
Also Don't use frameset and frames, use iframe instead
<iframe name="report" id="report" src="#">
also add this changeLink(); method call inside window load event
window.onload = function(){
changeLink();
};

Use JavaScript variable as iframe src?

I'm trying to use a JavaScript variable as the src in a <iframe>, the user will then be able to load other content by choosing scr in a menu, which changes the variable. the default src URL is apps/start.php.
Here some code from my index.php:
<script>
var appurl = "start.php";
document.getElementById("app").src = "apps/" + appurl();
</script>
<iframe id="app" src="">
</iframe>
The problem is that i can't get this first small part working... The <script> tag is in the <head>. And when the src is changing will the new document automatically load?
Wait for the page to load (note that this is only going to work when the iframe is on your domain)
window.onload = function(){
var appurl = "start.php";
document.getElementById("app").src = "apps/" + appurl;
};
The problem is that the Javascript is run before the iframe is there. Put your javascript below your iFrame or inside the document ready and it will work.
Example document onload:
<script>
window.onload = function ()
{
var appurl = "start.php";
document.getElementById("app").src = "apps/" + appurl();
}
</script>
<iframe id="app" src="">
</iframe>
<script>
window.onload = function ()
{
var appurl = "start.php";
document.getElementById("app").src = "apps/" + appurl;
}
</script>
<iframe id="app" src="">
</iframe>
Try
<script>
window.onload = function(){
var appurl = 'start.php';
document.getElementById("app").src = "apps/" + appurl;
};
</script>

Refresh all images with javascript?

I am trying to load the latest image from a CCTV server for each of our cameras on our network.
I have the following code, which works correctly and refreshes the image constantly. However, on the final version of the page there will be around 10 camera images on the page. I was wondering if the code I have now could be altered to refresh all images - not just specific ones.
At first I thought I could just use the same identifier for each image, but then I realised that the source of each image differs.
<html>
<head>
<title>CCTV Test</title>
<script type="text/javascript" language="JavaScript">
newImage = new Image();
function LoadNewImage()
{
var unique = new Date();
document.images.ward.src = newImage.src;
newImage.src = "http://192.168.1.64/image/WARD?time=" + unique.getTime();
}
function InitialImage()
{
var unique = new Date();
newImage.onload = LoadNewImage;
newImage.src = "http://192.168.1.64/image/WARD?time=" + unique.getTime();
document.images.ward.onload="";
}
</script>
</head>
<body>
<img src="http://192.168.1.64/image/WARD" name="ward" onload="InitialImage()">
</body>
</html>
Any pointers would be appreciated!
Something along the lines of this:
<!DOCTYPE html>
<html>
<head>
<title>CCTV Test</title>
</head>
<body>
<img src="http://192.168.1.64/image/WARD?time=...">
<img src="http://192.168.1.64/image/WARD?time=...">
etc.
<script>
setInterval(function() {
var images = document.images;
for (var i=0; i<images.length; i++) {
images[i].src = images[i].src.replace(/\btime=[^&]*/, 'time=' + new Date().getTime());
}
}, 10000); // 10000 milliseconds = 10 seconds
</script>
</body>
</html>
This will refresh all images every 10 seconds.
A different approach is to store the locations of the images in an array.

IE losing iframe contents after back/forward key

This problem is only happening in IE (at least 8 and 9). After an element is dynamically added to the DOM, the contents of an embedded iframe are lost when the page is reentered with a BACK/FORWARD key. Just two small HTML files will reproduce the issue.
The first file is iframe.htm:
<!DOCTYPE html>
<html>
<head>
<title>IE iframe bug</title>
<script type="text/javascript">
function mytrace(msg) {
var t = document.createTextNode(msg);
var b = document.createElement('br');
var d = document.getElementById("trace_output")
d.appendChild(t);
d.appendChild(b); /// will work if commented
}
function submitListing() {
mytrace('submitListing()');
var doc = document.getElementById("output_iframe")
.contentWindow.document;
var d = new Date;
doc.location.replace('report.htm?invalidateCache=' + d.getTime());
//mytrace('submitListing(): out');
}
</script>
</head>
<body>
<div id="trace_output"><br /></div>
<input type="button" onclick="submitListing();" value="Run" /><br />
<iframe id="output_iframe" src=""></iframe>
</body>
</html>
The second file is report.htm:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
LINK
</body>
</html>
Steps to recreate the issue (BACK KEY)
Place above content in two files
Browse the iframe.htm file
Press the Run button to load report.htm in the iframe
Click on the LINK link to load a different page
Press the browser BACK button to returned to the "cached" (lmao) page
iframe contents are gone!!!! (only in IE-- safari, chrome, firefox retain the contents)
Also..(FORWARD KEY)
Browse to an arbitrary page (for history, http://www.google.com works)
Load iframe.htm into the same tab
Press the Run button to load report.htm in the iframe
Press the browser BACK button to return to the first page
Press the browser FORWARD button to return to iframe.htm
iframe contents are gone again!!
Now comment out the line:
d.appendChild(b)
That one change allows everything to work in IE. However, my solution needs to make those kinds of DOM manipulations (heavy jQuery/AJAX app) AND be able to restore the iframe across browser BACK/FORWARD actions.
It seems that I will have to remember the contents of the iframe so that I can restore it when the page is accessed with the BACK/FORWARD keys. I'm not thrilled with this because sometimes the iframe content will be quite large and it could chew up a bit of memory and time to make another copy of the embedded document for the restore. I would love to hear some other ideas about how I could approach this. Thanks in advance.
EDIT
The following replacement to iframe.htm will work around the problem with IE. I'm going to rewrite this using jQuery and add some more logic to restore the scroll positions. I had hoped for something more elegant, but this is doing the job.
<!DOCTYPE html>
<html>
<head>
<title>IE iframe bug</title>
<script type="text/javascript">
function myTrace(msg) {
var t = document.createTextNode(msg);
var b = document.createElement('br');
var d = document.getElementById("trace_output")
d.appendChild(t);
d.appendChild(b);
}
var make_backup ="false";
function submitListing() {
make_backup = "true";
myTrace('submitListing()');
var doc = document.getElementById("output_iframe").contentWindow.document;
var d = new Date;
doc.location.replace('report.htm?invalidateCache=' + d.getTime());
//myTrace('submitListing(): out');
}
function iframe_load() {
myTrace("iframe loaded, is_cached=" + document.getElementById("is_cached").value);
if (make_backup == "true") { // only when submitting
var htm, doc;
make_backup = "false"
doc = document.getElementById("output_iframe").contentWindow.document;
htm = doc.documentElement.innerHTML;
document.getElementById("iframe_backup").value = htmlEscape(htm);
}
}
function bodyLoaded() {
var is_cached = document.getElementById("is_cached");
if (is_cached.value == "false") { // initial page load
is_cached.value = "true";
}
else { // BACK or FORWARD, restore DOM where needed
var htm;
htm = htmlUnescape(document.getElementById("iframe_backup").value);
var doc;
doc = document.getElementById("output_iframe").contentWindow.document;
doc.open();
doc.writeln(htm);
doc.close();
}
}
function htmlEscape(str) {
return String(str).replace(/&/g, '&').replace(/"/g, '"')
.replace(/'/g, ''').replace(/</g, '<').replace(/>/g, '>');
}
function htmlUnescape(str) {
return String(str).replace(/&/g,'&').replace(/"/g,'"')
.replace(/'/g,"'").replace(/</g,'<').replace(/>/g,'>');
}
</script>
</head>
<body onload="bodyLoaded();">
<div id="trace_output" style="height: 300px; border-width:1; background-color: Silver"><br></div>
<input id="is_cached" type="hidden" value="false">
<input id="iframe_backup" type="hidden">
<input type="button" onclick="submitListing();" value="Run"><br>
<iframe id="output_iframe" src="" onload="iframe_load();"></iframe>
</body>
</html>
EDIT 2
Rewritten with jQuery:
<!DOCTYPE html>
<html>
<head>
<title>IE iframe workaround2</title>
<script type="text/javascript" src="Scripts/jquery-1.7.1.js"></script>
<script type="text/javascript">
var make_backup = "false";
$(document).ready(function () {
myTrace('document ready()');
var is_cached = $("#is_cached");
if (is_cached.val() == "false") { // initial page load
is_cached.val("true");
}
else { // BACK or FORWARD, restore DOM where needed
if ($.browser.msie) { // IE loses iframe content; restore
var htm = htmlUnescape($("#iframe_backup").val());
var doc = $("#output_iframe")[0].contentWindow.document;
doc.open();
doc.writeln(htm);
doc.close();
myTrace('iframe contents restored');
}
}
$('#output_iframe').load(function () {
myTrace("iframe_loaded");
if (make_backup == "true") { // only when submitting
make_backup = "false"
if ($.browser.msie) {
var doc = $("#output_iframe")[0].contentWindow.document;
var htm = doc.documentElement.innerHTML;
$("#iframe_backup").val(htmlEscape(htm));
myTrace('iframe contents backed up');
}
}
});
$('#submit_listing').click(function () {
make_backup = "true";
myTrace('submitListing()');
var doc = $("#output_iframe")[0].contentWindow.document;
var d = new Date;
doc.location.replace('report.htm?invalidateCache='+d.getTime());
});
});
function myTrace(msg) {
$('#trace_output').append(msg + '<br>');
}
function htmlEscape(str) {
return String(str).replace(/&/g, '&').replace(/"/g, '"')
.replace(/'/g, ''').replace(/</g, '<').replace(/>/g, '>');
}
function htmlUnescape(str) {
return String(str).replace(/&/g,'&').replace(/"/g,'"')
.replace(/'/g,"'").replace(/</g,'<').replace(/>/g,'>');
}
</script>
</head>
<body>
<div id="trace_output"
style="height: 300px; border-width:1; background-color: Silver">
<br></div>
<div style="display: block;">
<input id="is_cached" type="text" value="false">
<input id="iframe_backup" type="text" type="hidden"></div>
<input id="submit_listing" type="button" value="Run"><br>
<iframe id="output_iframe" src=""></iframe>
</body>
</html>

call function on iframe mouse move

I have a function that i need to call on iframe mousemove(). But i didnt found anything like we have in body tag
We have <body mousemove="Function()"> Do we have anything like this for iframe??
The iframe contains its own document, own body element etc.
Try something like this:
var frame = document.getElementById("yourIframeId");
// IE is special
var frameDoc = frame.contentDocument || frame.contentWindow.document;
var frameBody = frameDoc.getElementsByTagName("body")[0];
var testingOneTwo = function() {
console.log("Hello, is this thing on?");
};
frameBody.onmouseover = testingOneTwo;
Did you mean onMouseOver or onFocus?
e.g.
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<script language="javascript">
<!--
function SayHello()
{
alert("Hi from IFrame");
}
//-->
</script>
</HEAD>
<BODY>
<iframe id="myiFrame" onMouseOver="SayHello()"/>
<iframe id="myiFrame" onFocus="SayHello()"/>
</BODY>
</HTML>

Categories