Added object tag to page via DOM methods - IE chaos
I’ve been working on a widget project that involves Flash and Javascript, and came across some very strange behaviour in IE6 / 7. The object tag to render the flash movie is dynamically added to the page at runtime using standard DOM methods - document.createElement, setAttribute, appendChild etc. Life was wonderful until I opened Internet Explorer, which hangs with what looks like a request for a file with no timeout (progress bar moving very slowly but never completing). This is identical behaviour to how IE behaves when the location of the SWF is invalid.
The markup
The markup I was generating was based on Flash Satay. Including this as static markup in a page works fine. Simple example below…
<object type='application/x-shockwave-flash' data='test.swf' width='420' height='155'>
<param name='movie' value='test.swf' />
</object>
DOM approach that chokes IE
The following approach causes IE to choke…
<script type="text/javascript">
var object = document.createElement('object');
object.setAttribute('type', 'application/x-shockwave-flash');
object.setAttribute('data', 'test.swf');
object.setAttribute('width', '100');
object.setAttribute('height', '100');
var param = document.createElement('param');
param.setAttribute('name', 'movie');
param.setAttribute('value', 'test.swf');
object.appendChild(param);
document.body.appendChild(object);
</script>
The solution / workaround
For some reason if the object tag + params are parsed at the same time everything works fine, so the solution involves using the alternate approach to manipulating the DOM - innerHTML. This wouldn’t have been my first choice given the situation, but it seems to be the only way to get this working. A version that works in IE…
<script type="text/javascript">
var fragment =
"<object type='application/x-shockwave-flash' data='test.swf' width='100' height='100'>" +
"<param name='movie' value='test.swf' />" +
"</object>";
var container = document.createElement('div');
container.innerHTML = fragment;
document.body.appendChild(container);
</script>
This achieves the same end result - a DOM element node that can be inserted anyway you wish, but avoid the problem in IE.
2 Comments
1 matt says...
Not sure if this is useful for you but I embed flash using the swfObject javascript as it gives you more control and avoids some problems with the regular embed method.
http://code.google.com/p/swfobject/
(Posted at 8:26 am on March 2nd, 2009)
2 Oli says...
I’m in a bit of a weird situation with this script, because it needs to work regardless of what is implemented on the host page.
This makes it impossible to introduce any real dependency on an external library etc, as I can’t really dictate the host page implements the library (and I can’t guarantee it’s not already there).
This either means a totally stand-alone script, or to bundle any dependencies with the script I offer. However that would double the size, and I’d need to handle the case where it already exists on the host page.
Still really in two minds about which is best, but for now I went with a stand-alone lightweight script without dependencies.
(Posted at 9:35 am on March 3rd, 2009)