Web standards compliant Javascript Flash detect and embed

FlashObject now has a permanant home at this url: http://blog.deconcept.com/flashobject/.

This post is partially out of date, and has been superceeded by Proper Flash embedding: FlashObject Best Practices. I’ve also closed the comments, please leave feedback in the new post.

Nearly every project I work on these days has Macromedia Flash involved with it some way or another. If you’re into the whole web nerd thing, you’ll know that embedding Flash in a XHTML page doesn’t play so nice with these web standards everyone is raving about. Developers basically have two choices these days when working with XHTML and Flash:

  1. The Flash Satay method, which uses a single object tag to embed the Flash movie. This method’s main drawback is that the movie won’t start playing until it is 100% loaded. This can create problems with large Flash sites where the user would be left with a blank screen until the movie loads. There are ways around this, but it involves using another swf file that loads your main movie and placing the preloader inside the first swf. This can clutter up your directories with ‘holder’ movies and make adding Flash content much more time consuming than it should be.
  2. Use Javascript to write the object / embed tags – This seems to be the most common way of embedding Flash today. Drawbacks include reliance on Javascript being enabled on the user’s browser, and having to include a .js file with each Flash movie, or rewrite the object and embed code for each movie.

With these in mind, I decided to come up with a standard way to embed my Flash movies, whether it be a single movie on a page (full Flash site) or multiple inline Flash elements on a larger XHTML page.

The features I wanted are:

  • Ability to embed unmodified Flash movies without the aid of other Flash movies
  • Ability to detect the Flash player version in the user’s browser and display alternate content if needed
  • Alternate content options – plain text (HTML), redirect, or image
  • Must validate as XHTML 1.0 transitional and up
  • Must accommodate any type of Flash embedding, including additional parameters and variables passed in via the Flashvars parameter
  • Easy to use (even non-technical designers should be able to use it!)
  • Must be able to be bypassed. What if the user has Flash but the detect failed for some unknown reason? (new browsers, unexpected plugin architectures, etc.)

With all this in mind, I started to look around for what other people have already come up with. Most large sites I looked at used simple Javascript to write each Flash movie to the page, or some reusable code that accepted parameters for the Flash movies. ABC News had the most advanced version I could find, with some excellent reusable Javascript that detected the plugin and could not only write the object and embed to the page, but could also target an element on the page and place the Flash movie inside it.

The ABC News code to write a Flash movie to the page looks like this:

var logo = new Flash("/flash/abcnewslogo.swf", 64, 64, 6);
logo.setParam("wmode", "transparent");
logo.render('logocontainer');

To view their Flash embed code, look here.

This isn’t bad at all, but it’s missing a few of my requirements: No way to specify alternate content if the user doesn’t have Flash (and no non-Flash site redirect option), and there’s no way to bypass it – if someone has some new unknown browser with a Flash plugin, and this script can’t find their plugin, there is no way they will get to see your Flash content.

So. Using this code as a base (except for the plugin detect, which I already had a copy I pieced together a while back and was basically the same thing anyway) I put together a new version with everything that I needed.

Here is what a basic Flash embed would look like:

var flashDial = new FlashObject("xm_dial.swf", "xmdial", 527, 349, 6, "#ABAFAE");
flashDial.write();

You can also target a specific element to place the Flash movie in by passing an element id in the write() method, like this:

myFlash.write('mydiv');

And here is a sample of what it would look like if you placed the code on the page and included alternate content and a few other optional parameters:

myFlash = new FlashObject("swffile.swf", "swffile", 500, 300, 6);
myFlash.altTxt = "<h1>You need to upgrade your Flash Player!</h1>";
myFlash.addParam("wmode", "transparent");
myFlash.addParam("salign", "top");
myFlash.addVariable("varname", "varvalue");
myFlash.write();

And that’s it! If you need to overwrite a default parameter, like quality, you would just set the parameter:

myFlash.addParam('quality', 'low');

If the user has Flash, they see the Flash movie. If they don’t, they will see your alternate text and a link to disable the Flash detect. This is done by simple adding detectflash=false to the query string (the link is added to the alternate text automatically unless you overwrite it).

Here is a sample page with a little Flash movie. Try uninstalling your Flash plugin and viewing the page.

I’ve also made a Flash template for this (included in the .zip file), so you can publish the javascript code you need directly from Flash – it’s not perfect, and only provides the very basic embed code, but it’s a nice starting point.

Download the FlashObject source code. Check out the updated version for the latest code downloads.

UPDATE (10-15-2004): Mark Wubben pointed out that there were couple loose variables hanging around, so I fixed that up. I decided to leave the getFlashVersion() function out in the open so it can be used independantly. Maybe you would want to use it to provide a general help statement without embedding a Flash movie?

UPDATE (10-20-2004): Just a small update, I removed the codebase variable since it will never be used by the browser. The only reason it’s in there is to give the browser a URI to download the plugin from, but since the Javascript won’t write the plugin code if they don’t have the plugin, it will never be used.

UPDATE (10-20-2004): I just posted a little follow up to the whole application/xhtml+xml mime types problem.

UPDATE (11-11-2004): Martin Klasson wrote and told me about how escape() tends to munge up some characters like ø and ä to name a couple. So I took it out, and switched the example page to utf-8 (because it should have been anyway). You’ll just have to watch out for things like double quotes being passed in through flashvars, but ideally you wouldn’t be doing that anyway, right?

UPDATE (11-13-2004): Just found a bug in the getQueryParamValue() function and fixed it. I should also note that you can use that function to grab URL parameters and send them to your Flash movie, so I added a little note in the usage comments on how to do that.

UPDATE (11-15-2004): Fixed a small bug pointed out by Manoloweb where the alt text would be written in the script tag instead of the target div if you specify a target. All fixed up now.

110 thoughts on “Web standards compliant Javascript Flash detect and embed

  1. Yes, addVariable passes the vars into the Flash movie using FlashVars, so it works the same as passing them in the query string, only you aren’t limited by URL string lengths in some browsers.

    It would look like this:

    myFlashObject.addVariable("varname", "value");

  2. Great script :)

    Instead of a text warning can an image be used as a replacement?

    Thanks

  3. Geoff said:
    Also keep in mind that every other XHTML valid method of embedding Flash that I have seen other than using JS (aside from the one that requires the extra XML file for each Flash movie) will not work 100% in Safari since it will ignore the param tags.

    Matteo:
    And remember… my TFL works fine also with js disabled! No work-arounds needed…

  4. But yours requires extra xml files, doesn’t include plugin detection, and Safari will still not see all the parameters passed in, like bgcolor (you have to re-publish your swf file if you change the bg color) and the right click menu – it will always show the menu in Safari.

  5. Pingback: snaptography.com

  6. I use FireFox’s strict JavaScript checking (about:config->javascript.options.strict=true), and it gives a warning for the line “FlashObject = function(swf, id, w, h, ver, c) {” that says “FlashObject” might not have been initialized. I added “var” to the beginning of that line, and the warning went away. You may want to do the same. Granted, FireFox is being a bit paranoid here, but I like to suppress unnecessary warnings as much as possible because sometimes FireFox does find real bugs this way.

    Nice implementation! Thanks for putting this out.

  7. Dave,

    Thanks, I’m currently rewriting the script, so I’ll add that into the new version.

    chrisgee,
    It looks fine to me in firefox on osx. You may be interested in the new version of the FlashObject script i’m working on – the new version will not write alt content by default, and it will replace your html on the page, so you don’t need the noscript tags any more – the flash will just replace your alt content.

  8. Geoff,

    Yes, I’m VERY interested in your new FlashObject script. Not to hurry you or anything but when do ya think you’ll have it done? ;-)

Comments are closed.