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.
You could use this Jquery code:
$("object[type='application/x-shockwave-flash']").append('<param name="wMode" value="transparent"/>');
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
});
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();
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>');
}
});
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
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"/>');
}