Introducing FLACCESS: flash keeping accessibility
2004-11-10 13:23:36
Detecting flash: previous methods
I have been trying to find a method of detecting, on the server, the presence of the flash plugin version installed in the browser. Even though it would be very easy for macromedia to add the version variable to to the HTTP_ACCEPT, they force us to use clientside languages to do so. Having that option would allow us to do content negotiation in server or simply add the flash satay method safely. The main problem with that method is that browsers with old plugins will load the object (thus not the alternate content) but will not understand the flash, and it cannot do streaming, although we can use a launcher for that, as in my previous attempt. Besides, some users have told me that the launcher method is not flexible enough (you cannot pass variables to flash) and it crashes in some browsers (like my Opera 7.23). These are the reasons that moved me to follow a different path.
Concept
The basic idea is similar to the sIFR concept: we have the alternate content somewhere in our html, then a script detects the plugin's version and if its ok it replaces the alternate content with the flash object. The advantge of this method is that unlike 99% of the other methods, if the browser doesn't have javascript or cannot load the flash object the alternate content remains in the html, so accessibility is high. In other methods, javascript writes both the flash object and the alternate content to the document, but if javascript is disabled neither are accessible. So lets get started...
How to use the script
The script is used as follows. Beware version 1.3 has some changes (make sure you read which changes), like addition of a lite version of the script.. First off, we need to link the script in the header of the html document:
<script type="text/javascript" src="flaccess.js"></script>
Add the alternate content (can be any html structure, like paragraphs, lists, etc) in an html element that has an id:
<div id="out">
<div id="in"> alternate content </div>
</div>
We need that element (and any flash object) to have at least position set in style declaration (absolute or relative) so that netscape 4 doesnt crash (we will explain that latter). So we can add that part to an external stylesheet or in a style block in the head:
#out {position:absolute; top:50px;left:50px;}
#in {position:absolute; top:0px;left:0px;}
object {position:absolute;}
If the element has ancestors, we have to add position to all of them. Otherwise netscape 4 will crash. To avoid having to use absolute positioning the ideal solution is setting all of them to relative (no need to set top nor left) letting elements flow along the page. If that makes netscape 4 not to show the appropiate layout, then we can use a special hack to add absolute positioning for those elements just in that browser.:
/*/*//*/
#out,#in,object {
position:absolute; /* */
}
/* */
Now we just need to call the function that adds the flash object instead of the alternate content element. Just after that element:
<script type="text/javascript">
// addFlash(postpone,minversion,path,width,height,node);
addFlash(0,5,"fl5.swf",200,100,"fl1,in,out");
</script>
Compulsory arguments of addFlash function
The addFlash function has some compulsory arguments that we explain now, in order:
- postpone
- (0/1) allows flash object to be loaded once page has loaded. This is ideal for banners because it lets the rest of the page load before it. Any other option will usually use value 0. Internally netscape 4 is an exception because it will always postpone the loading until page has fully loaded, because that browser cannot write to the layer if page is loading (and without a style for that layer). This argument is not used in lite version of this script.
- minversion
- minimum version of the plugin
- path
- path to the swf
- width, height
- width and height of the flash
- node
- hierarchical succession of ids to the element with alternate content. In our case, fl1 refers to the id of the flash object, in is child of out, and must be parsed in this order ("fl1,in,out"). If out was a child of another element called big wed pass "fl1,in,out,big". Do not use spaces in this string. This argument has been updated in version 1.3 (not flash id is compulsory)
Optional arguments of addFlash function
Then we have the optional arguments, that can be added after the node argument, separating name and value by colon (:) and arguments by a comma. The script handles the argumentos as parameters of the object or attributes of the embed, and if we dont use any default will be used. If you need a more technical explaination of each option you can use this one, I think all possibilities are taken into account.
- menu
- true/false
- play
- true/false
- devicefont
- true/false
- quality
- low/autolow/autohigh/medium/high/best
- scale
- noborder/exactfit/noscale/showall
- bgcolor
- hex color (ie. #ffffff)
- wmode
- window/transparent/opaque
- flashvars
- allows to pass variable names and values (more than one variable, separe them with an ampersand &)
- base
- base folder
- align
- (l, t, r, b) alignment respect to window
- salign
- (l, t, r, b, tl, tr, bl, br) alignment respect to window (dont know the difference with previous one)
- swliveconnect
- (true/false) used for communication with java
For example we could use
<script type="text/javascript">
addFlash(0,5,"fl5.swf",200,100,"fl1,in","menu:false","flashvars:a=3&b=www");
</script>
The script can be used in pages with other onload events thanks to Simon Willisons method that avoids overwritting old onload events. Apparently this method doesnt respect onload events set in body tag. This way we can add our own functions and events, and add as many flash objects as we want. The script is ment to keep all events separate.
Ive added a variable called flaccess_debug in case someone wants to get alerts in each intermediate step of the process, you only have to set it to 1 either in the js file or in any of the script blocks you open to call the flash.
Examples of use
Accessible text instead of flash 5
Final words
During my search for a method to detect flash in explorer using javascript I found an excellent method to insert flash objects that gets so close to what I wanted to achieve (actually, I borrowed the explorer detection), but isnt all I needed: doesnt allow it to be postponed until page has finished loading and doesnt work in netscape 4. I usually serve plain content and no script to that browser but in this situation I preferred to support it since I wanted t omake flash objects accessible in as many browsers as possible, including ie4+, ns4+, opera and safari (mac).
You can download the zipped files with examples from here (rar). Comments will be appreciated, and test results as well.