如何以编程方式将所有 <object> 设置为将 wmode 设置为不透明?

Posted

技术标签:

【中文标题】如何以编程方式将所有 <object> 设置为将 wmode 设置为不透明?【英文标题】:How do I programmatically set all <object>'s to have the wmode set to opaque? 【发布时间】:2010-11-13 04:48:47 【问题描述】:

我有一个客户正在将视频嵌入到他的 WordPress 博客中。问题是他们有一个很大的 CSS 下拉菜单,隐藏在 Flash 视频后面。我知道将视频的 wmode 设置为不透明可以解决此问题,但我显然需要将此应用于他们上传的每个视频,而不必转到 html 来添加此标签

有什么方法可以通过编程方式做到这一点?

【问题讨论】:

【参考方案1】:

为避免与我对先前答案所做的所有编辑混淆,我正在创建一个新答案,其中包含一个经过全面测试且工作正常的示例页面。它已经过测试并且可以在 IE 6、7 和 8、Opera 9.6 和 10、Safari 3 和 4、Google Chrome 中运行,但没有我测试过的 Firefox 版本(2、3 或 3.5):

<html>
<head><title>Opacity text</title></head>
<body>
<div style="color:Red;position:absolute;top:0px;left:0px;">
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br>
</div>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"  >
    <param name="movie" value="http://freevideocoding.com/flvplayer.swf?file=http://www.freevideoediting.com/TVQvideos/Queen Demo--flv.flv&autoStart=false">
    <param name="bgcolor" value="#ffff00">
</object>
<!--
all you need to make this work is the script listed below.
everything else is just sample code to provide a demonstration
that the script shown below actually works
-->
<script type="text/javascript">
function makeObjectsOpaque_TestedAndWorking() 
    var elementToAppend = document.createElement('param');
    elementToAppend.setAttribute('name', 'wmode');
    elementToAppend.setAttribute('value', 'opaque');
    var objects = document.getElementsByTagName('object');
    for (var i = 0; i < objects.length; i++) 
        var newObject = objects[i].cloneNode(true);
        elementToAppend = elementToAppend.cloneNode(true);
        newObject.appendChild(elementToAppend);
        objects[i].parentNode.replaceChild(newObject, objects[i]);
    

window.onload = makeObjectsOpaque_TestedAndWorking;
</script>
</body>
</html>

【讨论】:

【参考方案2】:

我认为问题在于您需要在嵌入标签内创建一个 wmode="opaque" 属性以及添加一个将 wmode 设置为“opaque”的 param 元素。虽然 Grant Wagner 的代码在将 wmode="opaque" 作为参数添加到对象中时是有效的,但它不会将其作为属性添加到 embed 标记中。如果你想让它跨浏览器、跨平台工作,你需要它们。这可能就是为什么 Grant Wagner 认为它有效,而 patricksweeney 则不然。

Josh Fraser 编写了一个很好的函数,它重写了 embed 标记以包含 wmode 属性。太好了,我结合了 Grant Wagner 的添加 wmode 参数的解决方案,以及 Josh Fraser 的添加 wmode 属性到嵌入到一个函数中的解决方案,它看起来有点像这样:

 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='opaque'");
            // add a new wmode parameter
            else 
                new_embed = html.replace(/<embed\s/i,"<embed wmode='opaque' ");
            // 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','opaque');
            embed.parentNode.replaceChild(new_embed,embed);
        
    
    // loop through every object tag on the site
    var elementToAppend = document.createElement('param');
    elementToAppend.setAttribute('name', 'wmode');
    elementToAppend.setAttribute('value', 'opaque');
    var objects = document.getElementsByTagName('object');
    for (var i = 0; i < objects.length; i++) 
        var newObject = objects[i].cloneNode(true);
        elementToAppend = elementToAppend.cloneNode(true);
        newObject.appendChild(elementToAppend);
        objects[i].parentNode.replaceChild(newObject, objects[i]);
    

window.onload = fix_flash;

这是一点点代码,但效果很好,它让我免于费时费力地拔头发。

【讨论】:

【参考方案3】:

既然你似乎已经放弃了this question,我就把答案贴在这里:

// makeObjectsOpaque() adds a <param> tag to each <object> tag
// analogous to <object ...><param name="wmode" value="opaque"></object>
// it seems unlikely that adding a <param> to an <object> dynamically after
// it has been rendered by the browser will actually apply the <param> value
// correctly; in other words, it *probably* WILL NOT WORK
function makeObjectsOpaque() 
    var elementToAppend = document.createElement('param');
    elementToAppend.setAttribute('name', 'wmode');
    elementToAppend.setAttribute('value', 'opaque');
    var objects = document.getElementsByTagName('object');
    for(var i = 0; i < objects.length; i++) 
        elementToAppend = elementToAppend.cloneNode(true);
        objects[i].appendChild(elementToAppend);
    


// makeObjectsOpaque2() adds a 'wmode' attribute to each <object> tag
// this should be analogous to <object ... wmode="opaque"> in HTML
// THIS DOES NOT APPEAR TO BE WHAT YOU WANT TO DO ACCORDING TO
// THIS URL: http://kb2.adobe.com/cps/127/tn_12701.html
function makeObjectsOpaque2() 
    var objects = document.getElementsByTagName('object');
    for(var i = 0; i < objects.length; i++) 
        objects[i].setAttribute('wmode', 'opaque');
        // you can also try:
        // objects[i].wmode = 'opaque';
    


// makeObjectsOpaque3() replaces every <object> tag on the page with
// a cloned copy, adding a <param> tag before replacing it
// analogous to replacing <object ...>...</object>
// with <object ...>...<param name="wmode" value="opaque"></object>
// this *may* cause the browser to re-render the <object> and apply
// the newly added <param>, or it may not
function makeObjectsOpaque3() 
    var elementToAppend = document.createElement('param');
    elementToAppend.setAttribute('name', 'wmode');
    elementToAppend.setAttribute('value', 'opaque');
    var objects = document.getElementsByTagName('object');
    for(var i = 0; i < objects.length; i++) 
        var newObject = objects[i].cloneNode(true);
        elementToAppend = elementToAppend.cloneNode(true);
        newObject.appendChild(elementToAppend);
        objects[i].parentNode.replaceChild(newObject, objects[i]);
    


window.onload = makeObjectsOpaque3;

如果已经有一个 onload 事件处理程序,您必须执行以下操作:

if(window.onload) 
    var onLoad = window.onload;
    window.onload = function() 
        onLoad();
        makeObjectsOpaque3();
    ;
 else 
    window.onload = makeObjectsOpaque3;

【讨论】:

如何从 onload 事件中调用它?只需为函数创建一个名称? @patricksweeney:我已经编辑了我的答案以演示如何将其附加到onload 谢谢,但它仍然无法正常工作。每次标签出现时都成功添加了,但还是不行。如果我手动添加它,它确实有效。困惑:( 我已经弄清楚出了什么问题。它需要在 @patricksweeney:您的意思是您需要为&lt;object&gt; 标签添加一个属性?我已经编辑了我的答案来证明这一点。【参考方案4】:

使用 jQuery,你可以试试这个:

$(document).ready(function()
    $("object").append('<param name="wmode" value="opaque">');
);

不完全确定这是否可行,但值得一试。祝你好运!

【讨论】:

实际上确实将它添加到每个元素中,但由于某种原因不起作用。我认为这是因为它在最后附加了它。不过感谢您的想法!【参考方案5】:

这个怎么样。它将它设置在对象上并作为一个参数(如果参数已经存在,它会更新它;否则,它会添加它)。

var setWmode = function(wmode, object) 
    $(object || "object").each(function(i, node) 
        // Set wmode on the object
        node.setAttribute("wmode", wmode);

        // See if wmode already exists to avoid duplication param conflicts
        var currentWmode = $("param[name='wmode']", node);

        // If it already exists, make sure its the new wmode
        if ( currentWmode.length ) 
            currentWmode.attr("value", wmode);
        
        // Otherwise, add it
        else 
            $(node).append('<param name="wmode" value="' + wmode + '">');
        
    );
;

$(document).ready(function() 
    setWmode("opaque");
);

【讨论】:

@Justin:我的测试表明,将&lt;param&gt; 添加到指向Adobe Flash Player 的现有&lt;object&gt; 标记实际上并不能完成任何事情。您必须克隆 &lt;object&gt;,添加 &lt;param&gt; 节点,然后在 parentNode 上调用 replaceChild() 以使其正确呈现。【参考方案6】:

作为记录,它需要在两个地方进行更改:请参阅here。

【讨论】:

以上是关于如何以编程方式将所有 <object> 设置为将 wmode 设置为不透明?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式清理 RAM 可可?

如何使用 Objective-C 以编程方式使我的 UIView 可水平滚动?

如何有效地将用户添加到 GitLab 中的所有项目(以编程方式或其他方式)

如何以编程方式将图像放入进度条(WPF)

如何以编程方式将 JS 和 CSS 资源添加到 <h:head>

在 iOS 7/Objective-C 中,如何以编程方式将 UIPickerView 捕捉到它所在的父视图的底部?