views:

24

answers:

1

I found a JavaScript error in a script that I'm developing. I whittled it down to a pair of fairly concise pages that still produce the error:

If you load the first page in Internet Explorer 8 (or probably 6 or 7, for that matter), give it about half a second to run the script, then click the "Google" link inside of the <iframe>, you should see an error message appear:

http://skitch.com/troywarr/dui21/ie8-error

(You may need to uncheck Tools > Internet Options > Advanced > "Disable script debugging (Internet Explorer)" and check "Display a notification about every script error" two lines below to see the error messages.)

Starting the debugger shows the beautifully insightful message "Object required":

http://skitch.com/troywarr/dui26/ie8-debugging

The culprit is the line:

target = event_object.target || event_object.srcElement;

I think that's valid code - at least it works in Firefox. My best guess is that there is an issue with trying to access the Event Object of one frame from another - vaguely similar to why you can't rely on instanceof to detect arrays if they were created in a different window/frame (search for "context" at http://javascript.crockford.com/remedial.html if that didn't make sense).

Does that sound like a valid theory? If so, what can I do to fix this? If at all possible, I need to preserve the same general code structure/functionality:

  • There is a link inside an <iframe> on a page.
  • A script in the <iframe> calls a function on the parent page, which attaches an event handler to the element in the <iframe> with the specified id attribute.
  • Clicking that <iframe>d link triggers the event, which calls a function on the parent page, passing the Event Object by default.
  • The function on the parent page determines information about the clicked element (the <a>) from the Event Object in a cross-browser-compatible way.

I would also like to continue using event delegation, and keep all of the functions in the parent document, just calling them with arguments from the <iframe>d document. However, if you have any suggestions for alternative approaches, I'd love to hear them.

Thanks in advance for any help! Please let me know if you need any more explanation about my requirements or what I'm trying to do - I'm hoping that there's just a better way to access or pass the Event Object that I'm not aware of - an "Oh, yeah, you just need to do it like this" kind of solution. I hope that's not wishful thinking. ;-)

+2  A: 

Easily fixed. You need the event object from the iframe's window. Store the iframe's window object next to where you store its document:

var iframe_win = document.getElementsByTagName('iframe')[0].contentWindow;

... and update the line that gets hold of the event object in your event handler function:

event_object = event_object || iframe_win.event;
Tim Down
Yup. I was not seeing the errors because my IE was boofed, but that's the issue.
Pointy
Awesome, thanks Tim! That worked. Is the contentWindow property compatible cross-browser?
Bungle
`contentWindow` is non-standard but supported in at least recent versions of all browsers. The DOM standard way would be `contentDocument.defaultView`. I decided not to complicate things by mentioning it, since you were already using `contentWindow` :)
Tim Down
Earleir versions of Chrome don't support `contentWindow`, so you should use `contentDocument` where possible.
Tim Down