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.

This entry was posted in Flash and tagged , , , . Bookmark the permalink.

4 Responses to Rendering Flash Content with Dynamic WMODE Attributes

  1. Josh says:

    You should check to see what show() and hide() actually do. If it removes the embedded content from the DOM entirely and adds it again, you should be fine. However, if it simply modifies the “display” or other related styles, then it’s important to note that browsers all behave a little differently. Some will reload the SWF entirely. Some will simply hide it, as those styles imply, but leave it running. Be sure to do cross-browser testing!

  2. My understanding is that they modify the “display” CSS attribute to “none” and back again.

    This is the trouble with HTML- while everyone cries “STANDARDS!” every browser still adheres to their own specific implementation.

    Straight-up doesn’t work in IE!

  3. Ryan Ragona says:

    Yeah, this just sets the object to ‘display: none;’ – and as Josh / Joseph pointed out, it does something different in each browser. (Nevermind those crazy Firefox browser bugs with wmode=transparent… grrr.)

  4. Pingback: Rendering Flash Content with Dynamic WMODE Attributes – Revisited | In Flagrante Delicto!

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">