Tuesday, March 13, 2007

Iframes and jQuery - Working with an iframe's parent

As I stated in my last post about iframe's and jQuery, the load event was only fired once in Internet Explorer, so this may be a problem in some situations (for instance, when you go to a new page in the iframe (which is the only reason I can think of for using one instead of includes)). You can put the code into the iframe and work with the page that contains it instead. This actually may be more desirable as it is simpler and works in more browsers (Firefox, Internet Explorer, Opera 8.54+ tested)

$( function() {
   var p = parent;
   $("a").click( function() {
       p.$("#myinput").val("Anchor clicked: " + this.href);
       return false;
   })
})

Iframes and jQuery - Working with an embedded iframe

IFrames, while they can be bad for accessibility (i.e. bookmarking), can also be very handy.

What I found was that working with iframes proved troublesome. I initially thought it would be as simple as this:

JavaScript
$( function() {
 $("#myiframe").load( function(){
  alert("Number of anchors: " + this.$("a").size());
  alert("Document title: " + this.document.title);
 });
});
HTML
<iframe src="myiframe.html" id="myiframe" name="myiframe"></iframe>

However, this caused several errors: this.document has no properties (i.e. this.document is undefined) and this.$ is not a function, so I had to find another way. After some trial and error in Internet Explorer and Firebug in Firefox, I found a way (which also works in Opera 9 as well, unsure about Safari though).

$( function() {
   var myiframe = $($.browser.msie ? frames["myiframe"] : "#myiframe");
   // doesn't work in Opera < 9
   myiframe.load( function() {
       var w = this.contentWindow;
       if(!w) w = myiframe[0]; // IE
       alert("Number of anchors: " + w.$("a").size());
       alert("Document title: " + w.document.title);
   })
})

Several things to note:

  • In Internet Explorer, if you navigate to a different page in the iframe, the load event is not fired again.
  • The iframe needs the id and name attributes to both be present and the same.
  • The iframe page also needs to include jQuery