parent.iframePDF is undefined - javascript

I get 'parent.iframePDF is undefined' JavaScript error when i use the below code in Firefox and an 'object expected' error in IE.
Can someone tell me what it is that i'm doing wrong? Thanks
function PrintFrame(xFile){
parent.iframePDF.location.href = xFile;
document.getElementById("spanMess").style.display = "block";
parent.iframePDF.onload = new function() {
setTimeout("parent.iframePDF.print();parent.document.getElementById('spanMess').style.display='none';",10000);
}
}
<iframe id="iframePDF" src="about:blank" style="display:none"></iframe>
<input type="image" onclick="PrintFrame('525.pdf')" src="../../cms_res/DisneyChannel/playhouse/images/buttons/printer.png" />
<span id="spanMess" style="display:none;color:red;">
<h3>Preparing Document For Print</h3>
</span>

You should use name="iframePDF" instead of id="iframePDF".
In that way, you can use window.iframePDF (-> window.frames.iframePDF).
If you use document.getElementById('iframePDF'), then you can't use .location.href on that.
Edit: Tim is right, no parent is needed here.

Your code may not work for succeeding calls of PrintFrame on other browsers, the problem is that the onload event on iframe may not fire anymore.
You may try this:
function frameLoaded(frame){
frame.contentWindow.print();
document.getElementById('spanMess').style.display='none';",10000);
}
function PrintFrame(xFile){
var holder = document.getElementById('iframePDFHolder');
holder.innerHTML = '<iframe onload="frameLoaded(this)" src=" + xFile + '"></iframe>';
}
<div id="iframePDFHolder" style="display:none;"></div>
<input type="image" onclick="PrintFrame('525.pdf')" src="../../cms_res/DisneyChannel/playhouse/images/buttons/printer.png" />
<span id="spanMess" style="display:none;color:red;"><h3>Preparing Document For Print</h3></span>

First problem is that parent refers to the window object of the document containing the current document and you actually want to call a function in the current document, so the parent is not required.
Second, you should use document.getElementById("iframePDF") rather than relying on IE's nasty featrue of creating properties of the global object corresponding to IDs of elements in the page. To get the iframe's window object you can use the (non-standard but widely supported) contentWindow property. Alternatively, assign a name to your iframe instead of an id and use window.frames["iframePDF"].
Third, new function() {...} is not what you want: the new there is not necessary and confusing; drop that.
Fourth, assigning an onload property to an iframe object will not work in all browsers. You need to handle the load event within the document loaded into the iframe and call a function in the main document, using parent to get hold of the containing document.

Related

HTML element no defined in Javascript

I have an html element:
<img alt="" src="../Images/ERROR.jpg" id="live1x4" height="288" style="width: 360px;
display: block;" /
If i refer to this control in javascript which is in the same html page:
live1x4.src = src;
Where src is the location of an image the script works.
If move that javascript to an external js file I get 'live1x4' is undefined.
This occurs ONLY in Internet Explorer.
Wjat can be causing this error?
You have to target your element, not simply refer to the ID:
document.getElementById("live1x4").src = ....
The reason is that the JavaScript code is executed before the img element has been parsed. Whether this happens depends on many things. There are different ways to ensure that it does not happen. A simple way is to wrap your code inside an even handler that is triggered after the document has been loaded:
window.onload = function() {
// your code here, here all elements are available, e.g.:
live1x4.src = src;
}
It is generally regarded as bad coding style to use id attribute values as if they were global variables (partly because they stop working ifsynonymous global variables are added), so document.getElementById("live1x4") is preferable to live1x4. However, this is a different topic.

Why is iframe.contentWindow == null?

I use the following code to dynamically create an iframe.
var iframe_jquery = $("<iframe>")
.addClass("foo")
.appendTo(container); // container is a jQuery object containing a <div> which already exists
Then, I want to access its contentWindow, but it's null:
var iframe = iframe_jquery.get(0);
if (iframe){ // iFrame exists
console.log(iframe.contentWindow); // Prints "null"
var doc = iframe.contentWindow.document; // NullpointerException
}
So I thought: "Maybe the iframe isn't ready yet?" So I tried:
iframe_jquery.ready(function(){
var iframe = iframe_jquery.get(0);
console.log(iframe.contentWindow); // Prints "null"
var doc = iframe.contentWindow.document; // NullpointerException
});
Same result.
What's wrong?
I had this problem last week while playing with iframes (building an rtf editor), and yeah it's not ready yet.
I thought if I put it in a .ready(), it would work, but .ready() is when the DOM is ready, not when the iframe has loaded its contents, so I ended up wrapping my code with jQuery .load().
So try this:
$(function () {
$("#myiframe").load(function () {
frames["myframe"].document.body.innerHTML = htmlValue;
});
});
Hope this helps
The problem is that your <iframe> won't be "real" until it's really added to the actual DOM for the page. Here is a fiddle to demonstrate..
Depending on the browser, accessing the document or an <iframe> may vary.
Here is an example of how to handle it:
if (iframe.contentDocument) // FF Chrome
doc = iframe.contentDocument;
else if ( iframe.contentWindow ) // IE
doc = iframe.contentWindow.document;
You can also make a function that will be executed when the iframe has finished loading by setting it's onload attribute.
Bookmarklet version
Just out of curiosity I thought I'd put this together. Remembering that iframes and load events don't play well together on different browsers (mainly older, falling apart, should-be-dead browsers)... plus not being entirely sure how jQuery gets around this problem... my brain decided that this would be better supported (whether it is or not is neither here nor there):
$(function(){
/// bind a listener for the bespoke iframeload event
$(window).bind('iframeload', function(){
/// access the contents of the iframe using jQuery notation
iframe.show().contents().find('body').html('hello');
});
/// create your iframe
var iframe = $('<iframe />')
/// by forcing our iframe to evaluate javascript in the path, we know when it's ready
.attr('src', 'javascript:(function(){try{p=window.parent;p.jQuery(p).trigger(\'iframeload\');}catch(ee){};})();')
/// insert the iframe into the live DOM
.appendTo('body');
});
The reason for taking this approach is that it is normally far better to trigger your load event from inside the iframe itself. But this means having a proper document loaded in to the iframe, so for dynamic iframes this is a little tedious. This is kind of a mixture between having a document loaded, and not.
The above works on everything I have tested so far - and yes you are correct - it is a little ridiculous, non-future-proof and propably other things that have negative connotations ;)
One positive thing I'll say about this post is that introduces the use of .contents() to access the document of the iframe, which is at least a little bit useful...

Accessing Elements Inside iframe and body Tags with JavaScript

I'm writing a GreaseMonkey script that modifies an attribute of an element with a specific ID, but I'm having some problems accessing it due to a nontraditional HTML hierarchy. Here's the relevant HTML:
<body>
...
<iframe id="iframeID">
<html>
...
<body id="bodyID" attribute="value">
...
</body>
...
</html>
</iframe>
...
</body>
Where attribute is the attribute that I'm attempting to modify.
At first, not realizing I was working with an iframe and a nested body tag, I tried this:
document.getElementById('bodyID').setAttribute("attribute","value")
While this worked fine in Firefox, Chrome tells me that I can't set the attribute of null, suggesting that it cannot find any elements with the id bodyID. How can I modify this attribute in a cross-browser friendly fashion?
You first need to pull the document of the <iframe>:
document.getElementById('iframeID').contentDocument
.getElementById('bodyID').setAttribute("attribute","value");
Live DEMO
BTW, if you want to get the <body> node, you don't need to give id or something like that, simply:
document.body
In your case, it's the document of the <iframe>:
document.getElementById('iframeID').contentDocument.body.setAttribute("attribute","value");
A lot simpler... Isn't it?
The best way, IMO, to do this is to listen for the load event fired by the iFrame, then look into the iFrame DOM as need. This guarantees that you'll have the iFrame DOM available when you need it and take a while shot.
$('#iframeID').on('load', function ()
{
alert('loaded'); // iFrame successfully loaded
var iFrameDoc = $('#iframeID')[0].contentDocument; // Get the iFrame document
$('body', iFrameDoc).attr('attribute', 'new value'); // Get the 'body' in the iFrame document and set 'attribute' to 'new value'
});

dom referencing only working correctly in IE

I have a javascript function that I am calling from an image onClick event in my page.
Basically the function sets a variable which is referencing an element within the same page.
here is how the function is called (note, the html is printed using PHP, but don't think that has any effect on the html itself):
echo "<img src='site/images/apps/show.gif' onClick='apps()' id='appbutton' style='#'>";
here is what the script references:
<iframe frameborder="0" name="app_frame" src="site/apps.html" width="0%" height="100%" scrolling="no"></iframe>
and finally, here is how it is referenced and what is done with it:
<script type="text/javascript">
function apps()
{
var element = document.getElementById("app_frame");
if (element.width == '0%')
{
parent.document.getElementById("frame").setAttribute("width","100%");
parent.document.getElementById("app_frame").setAttribute("width","0%");
parent.document.getElementById("appbutton").setAttribute("src","site/images/apps/show.gif");
parent.document.getElementById("wthrbutton").style.visibility="hidden";
}
else
{
parent.document.getElementById("frame").setAttribute("width","65%");
parent.document.getElementById("app_frame").setAttribute("width","35%");
parent.document.getElementById("appbutton").setAttribute("src","site/images/apps/hide.gif");
parent.document.getElementById("wthrbutton").style.visibility="visible";
}
}
</script>
The main issue is on the first line of the function, var element = document.getelementbyid.
Firefox, Chrome and Safari all hve issues with this, and none of them seem to set the variable, which renders the rest of the script useless, as the whole thing revolves around the variable.
Anyone know any other way of setting that element as a variable that would work in these browsers?
Thanks
That is because there is nothing with an id of app_frame. You have set the iframe's name to app_frame. Change your iframe's code to:
<iframe frameborder="0" name="app_frame" id="app_frame" src="site/apps.html" width="0%" height="100%" scrolling="no"></iframe>
An article pointing out this quirk in IE
MSDN's doc on getElementById states it returns names or id

How to add a click event to p elements in iframe (using jQuery)

How to add a click event to <p> elements in iframe (using jQuery)
<iframe frameborder="0" id="oframe" src="iframe.html" width="100%" name="oframe">
There's a special jQuery function that does that: .contents(). See the example for how it's works.
Your best best bet is to invoke the iframe AS LONG AS it's part of your domain.
iframe.html
<html>
<head>
<script>
window.MyMethod = function()
{
$('p').click();
}
</script>
</head>
<body></body>
</html>
And then use
document.getElementById('targetFrame').contentWindow.MyMethod();
To invoke that function.
another way is to access the iframe via window.frames.
<iframe name="myIframe" src="iframe.html"/>
and the javascript
child_frame = window.frames['myIframe'].document;
$('p',child_frame).click(function(){
alert('This click as bound via the parent frame')
});
That should work fine.
Wanted to add this, as a complete, copy-paste solution (works on Firefox and Chrome). Sometimes it is easy to miss to remember to call the event after the document, and so the iframe, is fully loaded:
$('#iframe').on('load', function() {
$('#iframe').contents().find('#div-in-iframe').click(function() {
// ...
});
});
The iframe must be on the same domain for this to work.
By giving a reference to the IFrame document as the second parameter to jQuery, which is the context:
jQuery("p", document.frames["oframe"].document).click(...);
To access any element from within an iframe, a simple JavaScript approach is as follows:
var iframe = document.getElementById("iframe");
var iframeDoc = iframe.contentDocument || iframe.contentWindow;
// Get HTML element
var iframeHtml = iframeDoc.getElementsByTagName("html")[0];
Now you can select any element using this html element
iframeHtml.getElementById("someElement");
Now, you can bind any event you want to this element. Hope this helps. Sorry for incorrect English.

Categories

Resources