Microsoft, ActiveX and noscript
Microsoft did it again and now it affected much broader user-base. The funny thing is – I remember Flash fans used to say that Flash is a kind of interface that will run equally on each platform/browser. Sweet…
Since April 11th, all IE 6 patches (and IE 7 betas for that matter) deployed this ActiveX… thing. Read more about it at Adobe/Macromedia, it’s too ugly to write about it here. What bothers me is that it affects my favorite Flash embedding method. Well, I guess, without this occassional crap – the life would be boring and I would be probably enjoying a cup of coffee somewhere in the down-town.
Whichever method you choose to fix this, one thing is certain – you’ll have to do it with JavaScript.
The sample workaround is deployed on the latest project from Burza, the Hellgate: London web site (if you’re reading this in the monday eve CET, check it out tomorrow), so you might want to take a closer look at this live example.
Basically, all we did was replacing a noscript content with some Flash embedding markup. The function for the external JavaScript file is:
/* parent id, flash object id, movie source, width, height, scale, salign, menu */
var ifl = function(eI,oI,m,w,h,scale,salign,menu) {
    var prnt = document.getElementById(eI);
    if (!prnt) return;
    var output = '<object id="' + oI + '" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="' + w + '" height="' + h + '">'
        + '<param name="wmode" value="transparent" />'
        + '<param name="allowScriptAccess" value="sameDomain" />'
        + '<param name="movie" value="' + m + '" />'
        + '<param name="quality" value="high" />'
        + (menu == 'false' ? '<param name="menu" value="false" />' : '')
        + '<param name="Loop" value="-1" />'
        + '<param name="Src" value="' + m + '" />'
        + '<param name="FlashVars" value="" />'
        + '<param name="Play" value="0" />'
        + '<param name="Loop" value="-1" />'
        + '<param name="SAlign" value="' + (salign == 'lt' ? 'lt' : '') + '" />'
        + '<param name="Base" value="" />'
        + '<param name="Scale" value="' + (scale == 'noscale' ? 'noscale' : 'ShowAll') + '" />'
        + '<param name="DeviceFont" value="0" />'
        + '<param name="EmbedMovie" value="0" />'
        + '<param name="BGColor" value="" />'
        + '<param name="SWRemote" value="" />'
        + '<param name="MovieData" value="" />'
        + '<param name="SeamlessTabbing" value="1" />'
        + '<embed src="' + m + '" quality="high" id="' + oI + '" name="' + oI + '" scale="' + scale + '" salign="' + salign + '" menu="' + menu + '" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="' + w + '" height="' + h + '" />'
        + '</object>';
    prnt.innerHTML = output;
};
	Cheating, right? Yes, but it’s also the fastest to render. Belive me, we tried a lot of methods. Plus, as I said many times before – users first, standards second.
This is sample HTML chunk. You can call the ifl function right after the corresponding element, right before the closing body tag or perhaps with onload event.
The most interesting fact is that if JavaScript is enabled – all the content inside noscript tags is not rendered, i.e. images are not loaded. Do you see the benefits? Inside the noscript tags you can create visually rich content wich will be loaded only if a user disabled JavaScript. Therefore the ‘test’ part of the JavaScript below. Try it to see what different browsers would ‘recognize’.
<div id="header">
    <noscript>
        <!-- noscript content goes here -->
        <p>For full experience, please <strong>enable JavaScript</strong> and <a href="http://www.macromedia.com/software/flashplayer/">get Flash player</a></p>
    </noscript>
</div>
<script type="text/javascript">
    /* <![CDATA[ */
        // test START
        if (document.getElementById && document.getElementsByTagName) {
            var summ = '';
            var ins = document.getElementById('header').getElementsByTagName('noscript')[0].childNodes;
            for (var i = 0; i < ins.length; i++) {
                summ += ins[i].nodeValue + ' ;  ';
            };
        };
        alert(ins.length + ' :  ' + summ);
        // test END
        ifl('header','flash_header','header.swf','300','200,'','','false');
    /* ]]> */
</script>
        
16 Comments
This just might be the fall for common flash-usage!
Comment (#) by Fredrik Wärnsberg — 8th May 2006.
Ugh! I’m glad I’m getting away from Flash… for a while I was feeling like I might be missing something. And, here it is - another headache. I can do without that! ;)
Just so you know - your live preview script is running r e a l l y s l o w today. Not griping - just letting you know.
Comment (#) by Chris Wible — 8th May 2006.
Very helpful, thanks.
Comment (#) by cody lindley — 9th May 2006.
We’ll be using this at work very soon.
Thanks a lot for sharing it.
Comment (#) by Nathan Logan — 9th May 2006.
Did you try using the SWFObject method of embedding Flash? I’ve found that to be the easiest and most effective way to embed Flash in a webpage, plus it has the advantage of detecting the version of Flash installed on a user’s machine. If you did try out SWFObject, I’m curious why you chose this solution in the end.
Comment (#) by John — 9th May 2006.
John, we tried with the SWFObject, but the site was awfully slow, especially on FF/Mac.
Comment (#) by marko — 9th May 2006.
we use SWFObject at work and it seems to work just fine, as well as it loads quite quickly.
Comment (#) by Darren Kopp — 9th May 2006.
SWFObject pushes P4 2.8 HT CPU to 100% in Firefox when cloud rendering starts at Hellgate: London.
We integrated a kind of benchmark into .SWF file itself, but it wasn’t of any help. Plus, we have tons of other JavaScript functions on the site, which is also making things more processor intensive.
Comment (#) by marko — 10th May 2006.
I agree with those above on the use of SWFObject:
(http://blog.deconcept.com/swfobject/)
The beauty of it is that is doesn’t rely on noscript at all – it replaces a DIVs content using well-written Javascript.
It keeps your markup extremely clean (a JS include and a few lines where you want the Flash to appear), and works in just about every browser. And where it doesn’t work, you’re left with a div containing your alternate content.
Nice work, though. And while SWFObject might be a teeny bit slower, it’s also far more flexible and time-tested at v1.4.
Comment (#) by Michael Thompson — 10th May 2006.
SWFObject pushes P4 2.8 HT CPU to 100% in Firefox when cloud rendering starts at Hellgate: London.
Are you sure? I’ve been using SWFObject for almost a year and a half and never had it affect the performance of a swf file. It just writes the html to the page as it loads and then that’s it, it shouldn’t cause any adverse performance.
Comment (#) by Geoff — 10th May 2006.
I’ve heard of CPU issues when SWFs are set with a transparent WMODE. Perhaps that could be the problem.
Comment (#) by Todd Dominey — 10th May 2006.
Todd, you’re right, the
wmode="transparent"increases CPU usage, but it’s sometimes necessary for various reasons. Nevertheless, the bruteinnerHTMLmethod works best in this case.Comment (#) by marko — 11th May 2006.
very nifty..thanks for sharing it..
Comment (#) by nivid — 18th May 2006.
I have heard SWF Object to be the most ideal solution, I just use a 5 line javascript i wrote that manually clicks on any object as it loads in the page, which works for all activex objects etc, especialy usefull if you have many flash objects on a page. (For example, an mp3 shopping site that has 50 preview buttons on one page, even though dynamically gen’d and swf object could be called for each one, its much more efficient).
And I thought how SWF Object worked coudln’t cause a big slowdown, but just now on a client’s site, It more then quadroupled the load time, it litteraly takes 30 seconds after the page is done loading for the flash to appear. Maybe it’s something specific for ceritant settings or flash files, but SWFObject definetly slower in this specific example (but has not been in others?).
Comment (#) by DC — 18th May 2006.
Yes, the SWFObject is great if you don’t have several Flash files plus loads of other JavaScript trickery around the page.
Comment (#) by marko — 19th May 2006.
There’s a much simpler way. No messing round creating hundreds of seperate Javascript files or relying soley on Javascript to “write” out tags.
This is basically a copy paste of what I posted on Robert Nyman’s blog.
At the moment I’ve got something like this at the top of the pages containing Flash or other ‘objects’.
<!--[if IE]><script defer="defer" src="iefixes.js" type="text/javascript"></script>
<![endif]-->
And in ‘iefixes.js’:
var objects = document.getElementsByTagName('object');for (var i = 0; i < objects.length; i++) {
objects[i].outerHTML = objects[i].outerHTML;
};
The two key points are the conditional comment (so it’s IE only) and the “defer” attribute (so it runs directly after the body is loaded).
It’s not perfect but it works well, and means I don’t have to change all object tags.
It also means that if the user doesn’t have Javascript they can still access the Flash.
Comment (#) by Karl Rudd — 23rd May 2006.
Sorry, the comment form is closed at this time, but if you have anything to say, please send me a message.