17
Rendering Flash Content with Dynamic WMODE Attributes – Revisited
Screw Internet Explorer! This is one of the many reasons I prefer to avoid having a browser render anything at all for me. Can’t trust it! Better to just take care of these things before it even hits the browser:
Java JSP example
1 2 3 4 5 6 7 8 9 10 11 12 13 | String embedCode1 = item.getEmbedCode(); String expression1 = "><param"; String replacement1 = "><param name=\"wmode\" value=\"transparent\"><param"; String embedCode2 = embedCode1.replace(expression1, replacement1); String expression2 = "<embed "; String replacement2 = "<embed wmode=\"transparent\" "; String embedCodeFinal = embedCode2.replace(expression2, replacement2); <div class="embedHolder"> <%=embedCodeFinal%> </div> |
What am I talking about? You can read up on my original article if it pleases you.
22
Rendering Flash Content with Dynamic WMODE Attributes
We all know that to have Javascript menus and such overlay embedded Flash content, that we need to set the WMODE parameter of our embed code to “opaque” or “transparent”. This is usually pretty simple if you are generating the embed code yourself through SWFObject, or even simply through HTML.
Here’s the thing… what if your application allows users to embed SWF content from YouTube, Vimeo, and other such services? What if your system generates little edit menus that happen to overlap such content? These services generally do not include the proper WMODE values to allow dynamic overlays. If you are just accepting SWF embed content, it’s a simple task to just parse the embed string and store the necessary values in your application to spit back out later using your own embed code formatting. What if there are just too many unknowns about the content your users may need to embed in the application? What if you also accept plain HTML embeds from services like Twitter and Facebook or other non-SWF content that you cannot parse attributes from so predictably? Then you need to do some more tricks to get that WMODE parameter set for any potential Flash content!
I use jQuery quite a bit when I absolutely need to deal with Javascript and like how it keeps the code from getting out of hand. It also provides a ton of extra functionality that is really useful when trying to identify certain elements in your HTML document for manipulation. I’d already tagged any user embed containing elements with a class of “embedHolder”, so using jQuery it would be super simple to identify all user embedded elements. So the original plan was to use both append() and attr() to modify any object or embed tag nested within any of these tagged container elements in order to add the necessary WMODE parameters:
1 2 3 4 | $(document).ready(function(){ $(".embedHolder object").append('<param name="wmode" value="transparent">'); $(".embedHolder embed").attr("wmode", "transparent"); } |
This doesn’t work though! It will certainly go through and modify the elements as needed, but since the SWF content has already been drawn into the viewport, the WMODE parameters are ignored. Thankfully, jQuery is super-awesome and includes both a show() and a hide() method. When you use hide() on an element, it will remove it from the viewport. Using show() will make it visible again. this effectively forces the browser to reload and redraw the SWF content, this time taking the WMODE changes into account perfectly.
1 2 3 4 5 6 7 8 9 | $(document).ready(function(){ $(".embedHolder object").append('<param name="wmode" value="transparent">'); $(".embedHolder embed").attr("wmode", "transparent"); $(".embedHolder").hide(); //a bunch of other code you may have $(".embedHolder").show(); } |
Awesome!
UPDATE 1: Errr… awesome in some browsers. As Josh points out below, the actual behavior differs quite a bit between browsers. No problem- I have a plan and will update this tomorrow with a solution. (hopefully!)
UPDATE 2: Yeah- IE is the only problem browser I’ve come across. Surprised? No.
UPDATE 3: Here is a solution for all browsers (even IE!):
1 2 3 4 5 6 7 8 9 10 | $(document).ready(function(){ $(".embedHolder object").append('<param name="wmode" value="transparent">'); $(".embedHolder embed").attr("wmode", "transparent"); $(".embedHolder").each( function () { var cont = '<div class="embedHolder">' + $(this).html() + '</div>'; $(this).replaceWith(cont); } ); } |
Now we are explicitly removing elements from the DOM and then reloading them into the same node, forcing the browser to redraw the SWF and activate the proper WMODE.
13
HTML Links in Flex
I’ve never found the need to have HTML links in Flex behave (and look) like their true HTML counterparts, but a student recently asked how she could get HTML links defined in a Text control to behave like regular HTML links. After digging around, I found a lot of references to this problem but the solution turned up at Flex Freaks:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:Script> <![CDATA[ import mx.core.mx_internal; public function textHandler(e:Event):void { var styleSheet:StyleSheet = new StyleSheet(); styleSheet.setStyle("a:link", { textDecoration: "underline", color: "#30F" }); e.currentTarget.mx_internal::styleSheet = styleSheet; } ]]> </mx:Script> <mx:Text initialize="this.textHandler(event)"> <mx:htmlText> <![CDATA[ You may <a href="">click</a> here. ]]> </mx:htmlText> </mx:Text> </mx:Application> |
Apparently, this should not be used with any degree of reliability so far as future-proofing is concerned since the mx.core.mx_internal class may flux between versions of the Flex SDK.
Listed in the rumored Flex 4 improvements are support for CSS descendant selectors, ID selectors, and space-delimited style names. Something like this should really be handled via CSS so here’s hoping that this will soon be a much simpler process.
Not sure if I’ll ever need this in the future, but in the case that I do- I know it’s here for easy access.










