HasanG
HasanG

Reputation: 13161

How to add wmode="transparent" for every flash object & ebmed tag?

I have a page which displays dynamic flash content from issuu.com. I need to add wmode="transparent" because otherwise navigation menu shows under flash. Is there a short way to do this with jQuery or simple java-script?

I don't want to change embed code every time a flash is added.

Upvotes: 7

Views: 24257

Answers (6)

danfromisrael
danfromisrael

Reputation: 3112

ok, after 2 days of searching the web for the answer i've found a pure JS function that fix it in all browsers!

there you go:

function fix_flash() {
    // loop through every embed tag on the site
    var embeds = document.getElementsByTagName('embed');
    for (i = 0; i < embeds.length; i++) {
        embed = embeds[i];
        var new_embed;
        // everything but Firefox & Konqueror
        if (embed.outerHTML) {
            var html = embed.outerHTML;
            // replace an existing wmode parameter
            if (html.match(/wmode\s*=\s*('|")[a-zA-Z]+('|")/i))
                new_embed = html.replace(/wmode\s*=\s*('|")window('|")/i, "wmode='transparent'");
            // add a new wmode parameter
            else
                new_embed = html.replace(/<embed\s/i, "<embed wmode='transparent' ");
            // replace the old embed object with the fixed version
            embed.insertAdjacentHTML('beforeBegin', new_embed);
            embed.parentNode.removeChild(embed);
        } else {
            // cloneNode is buggy in some versions of Safari & Opera, but works fine in FF
            new_embed = embed.cloneNode(true);
            if (!new_embed.getAttribute('wmode') || new_embed.getAttribute('wmode').toLowerCase() == 'window')
                new_embed.setAttribute('wmode', 'transparent');
            embed.parentNode.replaceChild(new_embed, embed);
        }
    }
    // loop through every object tag on the site
    var objects = document.getElementsByTagName('object');
    for (i = 0; i < objects.length; i++) {
        object = objects[i];
        var new_object;
        // object is an IE specific tag so we can use outerHTML here
        if (object.outerHTML) {
            var html = object.outerHTML;
            // replace an existing wmode parameter
            if (html.match(/<param\s+name\s*=\s*('|")wmode('|")\s+value\s*=\s*('|")[a-zA-Z]+('|")\s*\/?\>/i))
                new_object = html.replace(/<param\s+name\s*=\s*('|")wmode('|")\s+value\s*=\s*('|")window('|")\s*\/?\>/i, "<param name='wmode' value='transparent' />");
            // add a new wmode parameter
            else
                new_object = html.replace(/<\/object\>/i, "<param name='wmode' value='transparent' />\n</object>");
            // loop through each of the param tags
            var children = object.childNodes;
            for (j = 0; j < children.length; j++) {
                try {
                    if (children[j] != null) {
                        var theName = children[j].getAttribute('name');
                        if (theName != null && theName.match(/flashvars/i)) {
                            new_object = new_object.replace(/<param\s+name\s*=\s*('|")flashvars('|")\s+value\s*=\s*('|")[^'"]*('|")\s*\/?\>/i, "<param name='flashvars' value='" + children[j].getAttribute('value') + "' />");
                        }
                    }
                }
                catch (err) {
                }
            }
            // replace the old embed object with the fixed versiony
            object.insertAdjacentHTML('beforeBegin', new_object);
            object.parentNode.removeChild(object);
        }
    }
}

now you can just run in when the page loads with jQuery:

 $(document).ready(function () {
      fix_flash();
      // Call Function
 }); 

Upvotes: 11

filip
filip

Reputation: 3646

This is the most simple and browser-compatible solution I could find in order to remove wMode="window" objects AFTER the page has already been rendered.

In Internet Explorer, an object's child nodes cannot be modified once it has been inserted into the DOM. The best solution is to re-insert/re-render it by modifying outerHTML.

In most other browsers, modifying an object/embed's attributes is possible but has no effect once it has been rendered. Here, a re-insertion of the element at the same position causes a re-rendering. .wrap().unwrap() is the most simple way for this that comes up to my mind in jQuery.

$("embed[wmode=window], embed:not([wmode])").attr("wmode", "opaque").wrap("<div/>").unwrap();
$("object:has(param[name=wmode][value=window]), object:not(:has(> param[name=wmode]))").each(object);

function object() {
  this.outerHTML = this.outerHTML.replace(/<(?:[^">]+|(["']).*?\1)*>/, '$&<param name="wmode" value="opaque"/>');
}

Upvotes: 1

Trip
Trip

Reputation: 31

I couldn't get Mannaz version working, and wanted a more succinct jQuery function that re-writes the element into the page, so wrote a new one:

    function fixFlash() {
        $('object').each(function(){
            $(this).find('embed').attr('wmode','transparent');
            if($(this).find('param[name=wmode]').attr('value') != 'transparent') {
                $(this).prepend('<param name="wmode" value="transparent" />');
            }
            temp_var = $(this).parent().html();
            $(this).parent().html(temp_var);
        });
    }
    // Put function execute into onload area
    fixFlash();

Upvotes: 3

Leonardo Diaz
Leonardo Diaz

Reputation: 21

From another post here in stackoverflow, using JQuery this works

$("embed").attr("wmode", "opaque").wrap('<div>');

I use this when using a FCKeditor youtube plugin, as the plugin doesn't wrap the embed node with a object node.

  $('embed').each(function(){
    if($(this).parent()[0]['tagName'] !='OBJECT'){
      $(this).attr("wmode", "opaque").wrap('<div>');
    }
  });

Upvotes: 2

Juan Delgado
Juan Delgado

Reputation: 2030

Last time I checked, altering wmode by JS didn't work. Once the Flash object has been created, changing its wmode value has no real effect.

You would need to do this from either the backend or if that's not a possibility, in JS BUT before writing the object.

HTH

Upvotes: 1

whlk
whlk

Reputation: 15635

You could use this Jquery code:

$("object[type='application/x-shockwave-flash']").append('<param name="wMode" value="transparent"/>');

Upvotes: 8

Related Questions