SWFObject, IE and Dynamic Content (a problem)

I’ve got a problem. The main players are my plugin, Internet Explorer (7, maybe 8, not 6) and SWFObject.

The original inkling of issues came via Anon’s comment, on my previous update post, that YouTube videos pulled down as part of the “more” section were broken. I tested this locally and saw that, with IE7, he/she was right. Of course, it’s not just YouTube. It would be any of the <object>/<embed> elements video sharing sites provide.

That really sucks.

The Fix (sorta)

After spending one night trying to figure out what I could do to fix this, it became obvious that the generally accepted solution to dynamically adding those flash objects to a page is to use SWFObject, which:

Offers a JavaScript API that aims to provide a complete tool set for embedding SWF files and retrieving Flash Player related information

I really (always optimistic) thought this would be a quick set of changes to the javascript file; call the swfobject.embedSWF method and be done with it. Best of all, swfobject.js is already distributed with the WordPress install (which, by the way, I don’t see mentioned in the codex, the script handle to use to enqueue or set is as a dependency is 'swfobject'). But I couldn’t seem to get it to work, at least not in IE7.

That really sucks.

What IE Doesn’t Like

In the end, after much debugging with the uncompressed version of SWFobject, Firebug Lite and beaucoup de calls to console.log, I found the issue to be SWFobject’s call to outterHTML.

You see, when it creates this new element for the DOM, it needs someplace to put it. You provide the id of the element which will be used as that replacement. Sort of like the sacrificial lamb for the the new <object>. It’s through outterHTML that the replacement occurs. It sets the old element to be the new one.

435
el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';

createSWF function (line number as of version 2.2)

My plan was to replace the original object with the new one. When that didn’t work, I tried inserting a <div> as the target for replacement, right before the object, but that failed in the same way. Finally, I realized what was going on, and set as the replacement an item that already existed in the DOM (in other words, it wasn’t something pulled in and added dynamically by the RMRH plugin). That worked.

The problem seems to be that, when the element to be replaced has also been dynamically created, IE throws an exception when you try to change it. In other words, I created the sacrificial lamb and IE wants for it to have always existed.

The Fix Again (sorta, again)

But it bugged me that the call to outterHTML was the point-of-failure here. After all, I know I manipulate the DOM all the time in jQuery. Right? It provides replaceWith as part of its API after all, and that always seems to work.

So I replaced SWFObject’s call to outterHTML with jQuery’s replaceWith (does that count as ironic?), and the problem was solved.

So What Do I Do?

I don’t really want to change that one line and then bundle the modified swfobject.js file with my plugin. But that’s the only solution I can think of. Well, that and maybe just recreate (i.e. copy) the relevant SWFObject code in my javascript, to be used only with IE. But I can’t help but think there must be a better line of action here.

This has to be a relatively common situation. I mean, pull down content using AJAX, content happens to contain an embedded flash player, use SWFObject to make sure it renders in IE. I guess what’s missing is that in the common scenarios, an existing element is already set aside and ready to accept the new object. But I can’t do that with my plugin.

So what do I do?

15 thoughts on “SWFObject, IE and Dynamic Content (a problem)

  1. rbiggs

    This really is awesome … and somewhat surprising that a new version of swfobject.js doesn’t take this problem into account.

    One question: what would the new and improved (replaced) line look like? I’m guessing something like:

    $(el).replaceWith(” + par + ”);

  2. rbiggs

    (dang! I was hoping this blog software would simply render the HTML as text rather than strip it out. What I had written with the jquery replacement line was:

    $(el).replaceWith(“[everything that you had for el.outerHTML]“), … line 425.)

    Where can I find an uncompiled (non-min) version of the latest swfobject.js?

    Thanks! (ron: ron_biggs@msn.com)

  3. rbiggs

    Hey! I found the non-min version, replaced that line as you recommended and it did not work. What might i have done wrong?

  4. Woolie Post author

    I looked and (thankfully) still have the uncompressed version sitting here locally. It has the following line commented out:

    $j(el).replaceWith(‘<object classid=”clsid:D27CDB6E-AE6D-11cf-96B8-444553540000″‘ + att + ‘>’ + par + ‘</object>’);

    Try adding the ‘j’ (i.e. $j instead of $)

    Also, the line number at which I have that is 436 and the version of the file is 2.2. So unless you have a newer version it seems like line 425 might not be the right spot.

    Other than those two things, I’m not sure why it wouldn’t work.

  5. Graeme

    Thanks, your solution worked for me

    Comment out line 436 and put in a new line after with

    $(el).replaceWith(” + par + ”);

    Was getting error in IE only and now I don’t

    Thanks!!

  6. Tri Vuong

    I’m using swfobject 2.2 and I have the same problem. I tried to apply the fix that you guys are talking about there which is

    Replace this line

    //el.outerHTML = ” + par + ”;

    with this line
    jQuery(el).replaceWith(” + par + ”);

    However, it still not working for me. Any suggestion?

  7. nico

    same problem

    //el.outerHTML = ” + par + ”;
    $(el).replaceWith(” + par + ”);

    problem still present

    SWFOBJECt dont load on IE8 (no error message but flash not loading)

  8. mattb

    I had this problem with swfobject.js 2.2, and fixed it by doing the following.

    Changed this:

    aa.outerHTML=’”+af+””;

    to this:

    $(aa).replaceWith(‘”+af+””);

  9. bretto

    A better method of fixing this (if you don’t have access to the swfobject.js file) is you dynamically create a set of nested divs and tell swfobject to replace the inner one.

  10. Paul Moment

    After a day of rip-hair-out-of-my-bald-head frustration, this seriously saved my ass. Thanks so much for persistently tracking down a fix, Woolie. And thanks, mattb, for the code post. I wish some enterprising hacker would write a virus that would assassinate any version of IE it finds and replace with any other decent new-gen browser. Gawd. Thx again!

  11. Anton

    @Adam Duston, you are completely right.

    I’ve just spent the better part of a day trying to isolate why my externalInterface calls weren’t working (to SWF).

    Turns out that the BOZO that last worked on the site in question edited the minified swfobject.js without adding notes or ‘mod’ suffix to the file name.

    Please, please, please people if you are going to edit the swfobject.js, make sure you make it known that it has been edited!

    Or better yet; don’t.

    Cheers :)

  12. Nik

    hmm… i’m still getting an error in ie7 only (all others work)

    previous code

    //el.outerHTML = ” + par + ”;

    new code:
    $(el).replaceWith(‘”+par+””);

    anyone see any problems?

Comments are closed.