Lab: SWFObject: Examples & Tests
Note: This page contains outdated material. SWFObject has been updated to version 2.0, and uses completely different code syntax from previous versions of SWFObject. Unless otherwise noted, the examples provided on this page all use SWFObject v 1.5.1, and are NOT compatible with SWFObject 2.0.
SWFObject 1.5 (written by Geoff Stearns) is a non-obtrusive method of embedding a Flash SWF onto a web page. It lets you keep your markup clean, it generates simpler embed code than the traditional Adobe code, and it bypasses the EOLAS "click to activate" issue in Internet Explorer.
Lately I've spent a decent amount of time helping people at the SWFObject forum. This page lists most of the examples and proof-of-concepts I've whipped up in response to various forum posts, or out of my own curiosity.
Table of contents
- Ajax + SWFObject example
- ExpressInstall example
- Using JavaScript to write the swfobject.js link dynamically
- Full-screen SWF examples
- Hiding a SWF using Cascading Stylesheets (CSS)
- SWFObject + innerHTML
- Passing querystrings to a SWF
- SWFObject, Flash and the z-index
Ajax + SWFObject example
A poster had mentioned that he had done the following:
- Created an HTML page ("page A"), which contained a SWF that had been embedded via SWFObject
- Created an HTML page ("page B") that used xmlhttprequest (aka Ajax) to load the contents of page A into a DIV on page B.
He couldn't figure out why it wasn't working. There are two reasons I can think of:
- JavaScript events won't fire on a page that gets called via xmlhttprequest (in this case 'page A'). This means any content on 'page A' that is created dynamically by client-side scripts will not be created and will not transfer to the requesting page (page B). This includes any TEXT that is written by JavaScript on page load.
- To illustrate: Page A contains a single line of text. When loaded directly, JavaScript is used to add a second line of text. Page B loads page A using xmlhttprequest. When page A gets loaded into page B, the second line of text -- the one generated by JavaScript in page A's onload script -- does not appear.
- Embedded objects do not get passed by xmlhttprequest. Page markup gets passed, and that's about it. Video streams won't get passed, audio streams won't get passed, etc... only textual data may be passed. Hence the two options you get with xmlhttprequest: responseText and responseXML. (I'm no expert on the subject, but that's my understanding.)
A solution.
Keeping these facts in mind, if you need to load an external SWF onto your page, do it with SWFObject, not xmlhttprequest. Use xmlhttprequest to load external data about your SWF!
- Create the page you'd like to load a SWF into (for this demo, "index.html").
- Create the SWF, but don't embed it on any HTML pages (for this demo, "sample_flashvars.swf").
- Create an XML file containing the information needed for SWFObject, including any optional parameters you'd like to pass via FlashVars. This includes the SWF file path, width, height, minimum version of Flash, etc. (For this demo, "swfData.xml")
- Add an xmlhttprequest to the requesting page (index.html). The xmlhttprequest will load the swfData.xml file, then we use a little bit of JavaScript to extract the data.
- When the data has been extracted, it's used to populate an instance of SWFObject, which is then used to write the SWF to the page.
I know it sounds complicated, but it isn't, I swear! :)
The finished result. Here's the source FLA if you're interested.
ExpressInstall example
A simple example of using ExpressInstall to check for Flash Player version 8 and greater.
Using JavaScript to write the swfobject.js link dynamically
A poster wanted to embed a SWF onto a webpage, but wasn't allowed to add external links. In other words, he wasn't allowed to add this bit of code:
<script type="text/javascript" src="swfobject.js"></script>
This meant he couldn't use SWFObject. To get around this problem, I showed him that its possible to write the JS link dynamically using JavaScript.
Here's the script:
<script type="text/javascript">
document.write('<sc'+'ript');
document.write(' type="text/javascript"');
document.write(' src="swfobject.js">');
document.write('</sc'+'ript>');
</script>
Full-screen SWF examples
No, not the new 'fullscreen' mode, but the traditional "100%" width and height-style of full-screen.
Examples:
100% with a non-masked SWF (elements expand beyond the SWF's 'stage')
100% with a masked SWF (elements are masked IN THE FLA prior to export)
Hiding a SWF using Cascading Stylesheets (CSS)
Many people have asked how they can hide a SWF using JavaScript. There are two easy techniques for hiding a SWF using CSS. However, there are drawbacks to each technique, so be careful, and be sure to test the page in multiple browsers!
Using the negative text-indent CSS hack to hide the SWF.
This method hides the SWF while keeping the background DIV visible. This might be useful if you have a background image applied to your DIV. Working example. Works in Firefox 2 and IE 6 (WinXP).
function toggleSWF(){
var swfDiv = document.getElementById("flashcontent");
if(swfDiv.style.textIndent === "-9000px"){
swfDiv.style.textIndent = "0px";
} else {
swfDiv.style.textIndent = "-9000px";
}
}
Modified text-indent hack
It gets trickier if you want to hide the background DIV by making the DIV resize to zero (bringing all content below the SWF up while the SWF is gone, and moving it back down when the SWF re-appears).
This works fine in Firefox 2 (WinXP), but the DIV doesn't resize properly in IE6. In IE6, the box model forces the DIV's height to be as tall as the content it contains. Even though we've hidden the content with the negative text-indent hack, the content is still technically in the DIV, so it stays enlarged. Example.
Also note that when resizing the DIV in this manner, other CSS styling gets lost: the DIV's background color and border are somehow turned off in both Firefox and IE6.
function toggleSWF(){
var swfDiv = document.getElementById("flashcontent");
if(swfDiv.style.textIndent === "-9000px"){
swfDiv.style.textIndent = "0px";
swfDiv.style.width = "550px";
swfDiv.style.height = "400px";
} else {
swfDiv.style.textIndent = "-9000px";
swfDiv.style.width = "0px";
swfDiv.style.height = "0px";
}
}
Using "display: none" to hide the SWF
A nice and simple solution for hiding ANY div is to use "display: none". Example.
function toggleSWF(){
var swfDiv = document.getElementById("flashcontent");
if(swfDiv.style.display === "none"){
swfDiv.style.display = "block";
} else {
swfDiv.style.display = "none";
}
}
But again, this has a shortcoming: In Firefox 2, when you make the DIV visible again, it reloads the SWF and plays it from frame one. For some people, this is no big deal. However, if your SWF needs to receive JavaScript calls via ExternalInterface, this completely gums up the works. I won't get into the details here, but consider yourself warned!
Using innerHTML to hide the SWF
The same problem with reloading the SWF (the SWF starts from frame one) applies here. Please see the section titled SWFObject + innerHTML.
SWFObject + innerHTML
A number of people have asked whether SWFObject can be used with innerHTML. The answer is YES! Here's a working example.
BUT, as with many of the examples on this page, there is a drawback: using innerHTML to modify the SWF's DIV causes the "click to activate" EOLAS ugliness to re-appear in IE6. I don't currently have an answer for this, since I haven't really researched it.
I'm sure someone has an answer somewhere.
Passing querystrings to a SWF
Someone once asked about passing querystring parameters to a SWF on page load. This is a pretty simple task in PHP:
foreach($_GET as $variable => $value) {
echo "so.addVariable('$variable', '$value');";
}
ASP and other server-side languages will use similar techniques.
Full PHP example:
<script type="text/javascript" src="swfobject.js"></script>
<script type="text/javascript">
function addSwf(){
var so = new SWFObject('/lab/_common/sample.swf', 'sampleSwf', '550', '400', '7', '#000000');
<?php
foreach($_GET as $variable => $value) {
echo "so.addVariable('$variable', '$value');";
}
?>
so.write("flashcontent");
}
window.onload = function(){
addSwf();
}
</script>
SWFObject, Flash and the z-index
Sometimes you might want your SWF to go under some page elements. This has always been a tough nut to crack for Flash developers, because the Flash Player always writes the SWF on the topmost layer of the page, regardless of z-index order. This is especially annoying for people who use CSS-based menus, such as the famous Suckerfish menu method.
In this case, the answer is to use wmode="opaque" combined with a little extra CSS applied to the page elements:
<style type="text/css">
<!--
#flashcontent {
z-index: 2;
}
/* adding z-index to suckerfish menu */
#nav {
z-index: 3;
}
-->
</style>
<script type="text/javascript">
var so = new SWFObject('sample.swf', 'sampleSwf', '550', '400', '7', '#000000');
so.addParam("wmode", "opaque");
so.write("flashcontent");
</script>
Working example (using Suckerfish menu). Tested in Firefox 2 and IE6 (WinXP).
Read this article for more background info.