Currently I'm working on a website that uses Flash on one of its pages. As you should already know, ActiveX interaction is disabled in Internet Explorer because of the Eolas issues. You can read more about this in the Activating ActiveX Controls article published in MSDN.
Since I want to write in valid HTML only, the HTML code should be written as something like this:
<object type="application/x-shockwave-flash" data="example.swf">
<img src="example.png" alt="Alternate content">
</object>
This works perfectly on anything but IE. In order to make IE happy, we have to add an extra param
element:
<object type="application/x-shockwave-flash" data="example.swf">
<param name="movie" value="example.swf">
<img src="example.png" alt="Alternate content">
</object>
Now IE knows where the movie is and loads it properly. But the ActiveX control is disabled from user interaction. So a little JScript is needed here.
By googling, I came up with this informative blog post: Flash interaction disabled in Internet Explorer. The solution by David Merrilees is almost perfect. The idea is to remove the data
attribute not recognized by IE, recreate the whole object
element using outerHTML
, and using CSS to prevent flickering.
But he is missing one important thing: what about user with JScript disabled, CSS enabled and Flash plugin installed and enabled? They will see nothing because the visibility
is set to hidden initially.
So, instead of hiding the objects for all IE users, what about hiding the objects for all IE users with JScript enabled? While ideally we should use DOM method to modify the HTML content, we can't do so here as it will be already too later if we hide the Flash movie until window.onload
. Fortunately, we can use document.write
to output stylesheet that hide the objects before the document is loaded:
document.write( '<style type="text/css">' );
document.write( 'object { display: none }' );
document.write( '</style>' );
While I personally hate using document.write
, it is OK here as IE only supports HTML (specifically (X)HTML served as text/html).
So the rest is almost identical to David Merrilees's solution, except that I've used display: none
instead of visibility: hidden
as I found it not working for me.
HTML
Conditional comment is used so that only IE will run this JScript (activex_fix.js). Be sure that it is included inside the head
element, not the body
element.
<!--[if IE]>
<script type="text/javascript" src="activex_fix.js"></script>
<![endif]-->
JScript (activex_fix.js)
window.attachEvent
is used, so that it won't mess up other cross-browser onload handlers like window.onload
(or better, DOMContentLoaded).
// Hide objects to prevent flickering when recreating the objects
document.write( '<style type="text/css" id="activex_fix">' );
document.write( 'object { display: none }' );
document.write( '</style>' );
// Recreate and reveal the hidden objects
window.attachEvent( "onload", function()
{
// Recreate the objects
var objects = document.getElementsByTagName( "object" );
for ( var i = 0; i < objects.length; i++ )
{
var object = objects.item(i);
// Fix flash object
if ( object.type == "application/x-shockwave-flash" )
{
if ( object.getAttribute("data") )
{
object.removeAttribute( "data" );
}
object.outerHTML = object.outerHTML;
}
}
// Reveal the objects by removing the stylesheet created by document.write
var stylesheet = document.getElementById("activex_fix");
stylesheet.parentNode.removeChild( stylesheet );
} );
This idea should also work for Opera 9, which follows IE's decision to disable user interaction with plugin content. I didn't bother to deal with it as it is not required by the client. :-P