« All that work, so long ago | Main
15, 2006
Flash, WMode, Scrolling, and Overflow:auto in Firefox
As any developer who has used flash in a webpage that contained overlays like lightbox or even drop down navigation menus will know, in its normal mode of operation Flash content will appear above all other layers on a web page. To allow flash content to be layered with other elements, you must set the WMode property to either "transparent" or "opaque" (Transparent will allow content behind the movie to show through transparent areas.):
<param name="wmode" value="transparent">
<embed ... wmode="transparent" ...>
This works very well in Internet Explorer, but there are several problems in Firefox.
The first is an easy fix: If the flash content is contained in an absolutely positioned element, and that element has its overflow peoperty set to auto, the mouse events in the flash object respond as if the flash was positioned in the upper left hand corner of the page, no matter where it actually is. To fix this you can simply set the overflow property to none.
As long as your flash is on a page that does not need to scroll, that will fix the problem. However, if the page scrolls, mouse events will be offset by the scroll height of the page, rendering any flash that initially loaded below the fold inaccessable to the mouse entirely.
The fix
The solution to this problem is to dynamically create iframes to contain the affected flash content when viewed in Firefox. Iframed content will layer properly, and the flash will always be in the upper left hand corner of its framed document.The following code relies on the availability of the jquery library and Michael Geary's DOM creation tool.
function iframeSwitch()
{
//find flash content container and grab contents
//(should only be object and embed tags)
var container = $("#flash_content");
var c = container.html();
//get the size from the object element
var object = $("object",container);
var x = object.width();
var y = object.height();
//create the iframe element, hidden for now
var frame = $.IFRAME({
id:'graph_content_frame',
frameborder:'0',
marginwidth:'0',
marginheight:'0',
scrolling:'no'
});
$(frame).css('display','none');
//attach the iframe to the document and remove the
//old flash container element
container.after(frame).remove();
//set the size, open the iframe, and insert
//the flash content.
$("#graph_content_frame")
.css('border','none')
.height(y+'px')
.width(x+'px')
.css('display','block')
.each(function(){
this.contentDocument.open();
this.contentDocument.write(c);
this.contentDocument.close();
});
}
Posted by tom at 15, 2006 11:44