Removing the Flash border in IE (ActiveX content)

if you have visited a website lately that uses Flash, perhaps you have noticed a thick gray border around the Flash movies that you could have sworn wasnt there before. it isnt there in Firefox or Safari or Opera, only in IE. well, no, you arent losing your mind - it really *didnt* used to be there.

back in february (2006), Microsoft released an update to IE that causes this change. the change was a patch released in response to a lawsuit brought against Microsoft by Eolas, who claimed they held a patent on embedding content in the browser using 'plug-ins'. after a victorious judgement for Eolas, Microsoft decided to just change the behavior of IE instead of pay the judgement (something to the tune of $500 million dollars - you can read more about it at http://www.digitalproducer.com/articles/viewarticle.jsp?id=38506)

so now unsuspecting users who use Windows Update will get the patch and perhaps wonder what the heck happened. Microsoft announced the change (http://support.microsoft.com/kb/912945/en-us) and even provided a work-around to the ensuing problem (http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/overview/activating_activex.asp). Seems as though even they knew this change was a bonehead move and developers would immediately be wanting to get around it. The solution Microsoft offered up was essentially to remove the OBJECT and EMBED tags from your HTML and instead dynamically write them out using JavaScript.

for their part, Macromedia (err...Adobe) knew that this change would reflect badly on them, even though they were innocent bystanders as well. they proposed their own solution(http://www.adobe.com/devnet/activecontent/), which was essentially the same solution as Microsoft, but geared a little more toward Flash developers.

while both of these solutions work, they are more than a little bit crude. a nifty little utility called SWFObject (formerly FlashObject - http://blog.deconcept.com/swfobject/) can be used to avoid the problem, and provides some other features like Flash-plugin detection. still, at the heart of this solution is still dynamically writing out your HTML via JavaScript.

i decided that a new approach was needed. i set the following requirements for any solution:

  • OBJECT and EMBED tags should be in regular HTML and work as normal
  • minimize changes required for developers to implement the solution
  • be cross-browser compatible
  • still allow Flash content for users who have turned off JavaScript

the solution i came up with is actually quite simple. it involves simply wrapping the normal OBJECT and EMBED tags in a NOSCRIPT tag like this:

<noscript id="ActiveContent">
<object attributes...etc>
<embed attributes...etc>
</object>
</noscript>
in addition, a small chunk of javascript is included in an external .js file that performs the magic:
var flashContainer = document.getElementById("FlashMovie");
var flashMovie = document.createElement("div");
flashMovie.innerHTML = decode(flashContainer.innerHTML);
flashContainer.parentNode.insertBefore(flashMovie, flashContainer);
function decode(input)
{
var output = input;
output = output.replace(/</g, "<"); output = output.replace(/>/g, ">");
return output;
}


essentially, all it does is read in the contents of the NOSCRIPT tag, and then write them back out in a new, dynamically added DIV tag. The 'decode' function is necessary because Firefox automatically escapes the contents of the NOSCRIPT tag (i dont know why and could not find any documentation about it - other HTML tags do not exhibit this behavior). some of you might cringe at the use of innerHTML, but in this case, it fits the bill perfectly and is still way better than using document.write and concatenating the HTML string together.

this solution fufills all of the initial design goals:
  • the OBJECT and EMBED tags remain in the HTML source, full editable like normal
  • the changes simply require wrapping the intial code in a NOSCRIPT tag and linking in the external .js file, minimizing tedious changes for developers
  • the technique works across all various current-generation browsers
  • unlike the Microsoft and Adobe solutions, this solution still displays the Flash content if the user has JavaScript turned off since it naturally fails back to the NOSCRIPT content anyway (of course, the original problem of the border still exists, but no functionality is lost and this is a small segment of the population)

the code here is very simple but could easily be extended to automatically handle multiple different Flash objects on the same or multiple pages (document.getElementByTagNames looking for OBJECT would be a good start, then just traversing the DOM tree to get the elements you needed). come to think of it, you could probably get by without the NOSCRIPT altogether and just find the OBJECT content and re-write it out dynamically while nulling out the original innerHTML.

hopefully this will help those of you who have been frustrated by this recent 'feature' released by Microsoft.

 

6 comments

  1. Can you post a working example and/or supporting files for this method?

     
  2. I hope you don't mind, but I cleaned it up a little... my version lets you leave the object/embed tags the way they used to be, and it's all changed dynamically.

    fixflash.js:
    ========================================
    function fixflash(containerID){
    var flashContainer = document.getElementById(containerID);
    var flashMovie = document.createElement("div");
    flashMovie.innerHTML = flashContainer.innerHTML.replace(/</g, "<").replace(/>/g, ">");
    flashContainer.parentNode.insertBefore(flashMovie, flashContainer);
    flashContainer.parentNode.removeChild(flashContainer);
    flashMovie.setAttribute("id",containerID);
    }

    slideshow.html:
    ========================================
    <html>
    <head>
    <script language="javascript" src="fixflash.js"></script>
    </head>
    <body onload="javascript:fixflash('slideshow');">
    <div style="height:600px; width:800px;" id="slideshow">
    <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="800" height="600" id="SlideShow.swf" align="middle" VIEWASTEXT>
    <param name="allowScriptAccess" value="sameDomain">
    <param name="movie" value="SlideShow.swf">
    <param name="quality" value="high">
    <param name="bgcolor" value="#000000">
    <param name="scale" value="exactfit">
    <param name="menu" value="false">
    <param name="loop" value="false">
    <embed src="SlideShow.swf" quality="high" bgcolor="#000000" width="800" height="600" name="SlideShow.swf" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer">
    </object>
    </div>
    </body>
    </html>

     
  3. Thanks, Good work

     
  4. Anonymous

    Thank you, ..but I have 6 falsh objects on my page and the screen loads strangely (it flics), is there a solution for that?
    thanks
    tara

     
  5. Purple

    Great work. Thanks for the quick fix.

     
  6. GLITCH42

    Works great! Thanks!