[轉] RX8012: 不同瀏覽器中 Flash 與其他元素髮生覆蓋時有差異

標準參考

堆棧級 stack level 概念請參見 CSS 2.1 規範:9.9 Layered presentation

'z-index' 特性對 stack level 的影響,請參見 CSS 2.1 規範:9.9.1 Specifying the stack level: the 'z-index' property

問題描述

不同瀏覽器中 Flash 與其他元素髮生覆蓋時, Flash 與其他元素的層疊順序有差異。

造成的影響

Flash 被其他元素遮擋,或其他元素被 Flash 遮擋,與期待效果不同。

受影響的瀏覽器

所有瀏覽器  

問題分析

一般情況下,頁面中會用 OBJECT 與 EMBED 元素來顯示一個 FLASH 動畫。大致代碼如下:

<object type="application/x-shockwave-flash" data="clock.swf
">
  <param value="clock.swf
" name="movie"/>
  <param value="wmode" name="window"/>

</object>

OBJECT 元素內 PARAM 元素負責爲 Flash 動畫設置相應參數,其中 wmode 參數較爲重要,它決定了 Flash 的渲染方式。

Adobe 公司的 Flash 開發者文檔中有關於 wmode 參數值的詳細說明: Support for WMODE

當 wmode = "transparent" 或 "opaque" 時,Flash 動畫交由頁面渲染引擎負責渲染,此時它在定位流中的位置由 CSS 中的 'z-index' 特性控制。

如果 wmode 沒有設置,他的默認值是 window,這代表 Flash 動畫將在 window 窗口級別渲染,相應元素擁有系統級的窗口句柄,它所在定位流中的 'z-index' 特性將失效,而會處於所有未擁有窗口句柄特性的頁面元素之上,此時用來控制定位流中 Z 軸方向中上下層位置的 'z-index' 特性將會失效。

分析如下代碼:

<body style="margin:40px;">
  <object type="application/x-shockwave-flash" data="clock.swf
" style="height:80px; width:80px; position:absolute; top:0; left:0;">
    <param value="clock.swf
" name="movie"/>
    <param value="wmode" name="window"/>

  </object>
  <iframe src="http://www.google.com/logos/
" style="width:240px; height:120px;"></iframe>
</body>

頁面中用來播放 Flash 的 OBJECT 元素被設置了絕對定位 position:absolute,使其處於定位流中,'z-index' 特性沒有設置,採用默認值 auto。此時它已不在普通流中佔有位置。

由於其本身已經處於定位流中,頁面中其他元素均處於普通流中,它本身還在窗口級別渲染,其他定位流中元素也無法覆蓋它。因此可以斷定它會遮擋住其後的 IFRAME 元素顯示。

觀看實際情況:

IE6 IE7 IE8 Firefox Safari Opera Chrome

IE6 IE7 IE8 Firefox Safari Opera 瀏覽器中顯示情況均與相關規範吻合。但是 Chrome 中處於普通流中的 IFRAME 元素卻將擁有窗口句柄的定位流中元素覆蓋。

造成這個問題的情況只能有一種,即在 Chrome 中 IFRMAE 元素實際上擁有窗口句柄,雖然這個句柄無法使用 SPY++ 等窗口句柄信息查看工具獲取到。

根據 window 窗口建立的規律,後建立的窗口會擁有更高的堆棧級別,覆蓋於最先建立的窗口上。

我們只需將原始代碼中的 IFRAME 元素放置到 OBJECT 元素之前,使它先被創建,觀察其是否被後創建的 OBJECT 覆蓋,就可以證實這個推測:

<body style="margin:40px;">
  <iframe src="http://www.google.com/logos/
" style="width:240px; height:120px;"></iframe>

  <object type="application/x-shockwave-flash" data="clock.swf
" style="height:80px; width:80px; position:absolute; top:0; left:0;">
    <param value="clock.swf
" name="movie"/>
    <param value="wmode" name="window"/>

  </object>
</body>

觀看實際情況:

所有瀏覽器

根據上表可以看出,實際情況與猜測情況相吻合。

絕對定位元素與 Flash ( wmode = "window" )重疊時,當 'background' 的特性值不是 'transparent' 時, Firefox 中絕對定位元素卻可以遮擋 Flash ,其它瀏覽器都不能遮擋 Flash 。

分析以下代碼:

<!DOCTYPE HTML>
<html>
    <head></head>
    <body style="margin:40px;">
  <object type="application/x-shockwave-flash"
    data="clock.swf"
    style="height:80px; width:80px; position:absolute; top:0; left:0;">
    <param value="clock.swf" name="movie"/>
    <param value="wmode" name="window"/>

  </object>
  <div style="top:0;position:absolute;
 left: 0;background: gold;">this is test word this is test word</div>
    </body>
</html>
      

以上代碼在不同瀏覽器中表現如下:

Firefox IE6 IE7 IE8 Chrome Safari Opera

絕對定位元素是 iframe 時與 Flash ( wmode = "window" )重疊, IE 和 Chrome 中 iframe 會遮擋 Flash ,而Firefox Safari Opera 中 Flash 會遮擋iframe

分析以下代碼:

<!DOCTYPE HTML>
<html>
    <head></head>
    <body style="margin:40px;">
  <object type="application/x-shockwave-flash"
    data="clock.swf"
    style="height:80px; width:80px; position:absolute; top:0; left:0;">
    <param value="clock.swf" name="movie"/>
    <param value="wmode" name="window"/>

  </object>
  <iframe src="about:blank" class="cover_iframe" width="200" height="50" frameborder="1" scrolling="no" style="position:absolute;
top:0;left:0;"></iframe>
    </body>
</html>
      

以上代碼在不同瀏覽器中表現如下:

IE Chrome Firefox Safari Opera

有沒有辦法讓 iframe 元素在所有瀏覽器下都可以遮擋 Flash呢?

分析以下代碼:

<!DOCTYPE HTML>
<html>
    <head></head>
    <body style="margin:40px;">
    <embed type="application/x-shockwave-flash"
    src="clock.swf" 
    style="height:80px; width:80px; position:absolute; top:0; left:0;" wmode="transparent">
    </embed>
  <iframe src="about:blank" width="200" height="40" frameborder="1" scrolling="no" style="position:absolute;top:0px;left:0px;background: gold;"></iframe>
    </body>
</html>
      

以上代碼在不同瀏覽器中表現如下:

IE Firefox Chrome Safari Opera

解決方案

若有頁面需求是要求其他元素遮擋 Flash

  • 1.使用 EMBED 引入Flash 。
  • 2.wmode的值使用 'transparent' 或 'opaque' 。
  • 3.使用的 iframe 需要設置背景色(設置爲白色)。

注意:當wmode的值不是window時,Flash中有可能無法切換輸入法,該問題爲插件問題,期待插件廠商修復。關於 IE 和非IE瀏覽器背景色不同的問題請參見RC3001: IE6 IE7(Q) IE8(Q) 中 IFRAME 元素 'background-color' 特性默認值不是 transparent

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章