引入Flash那些事
最近做的事和Flash打交道比較多,簡單來說,就是要在第三方的頁面引入一個Flash的廣告,播放一會,讓用戶能夠關閉。
起初總覺得,就引入一個Flash嘛,adobe都給出了官方的使用方法,直接拿來用不就成了。頂多IE下不支持object元素的appendChild,大不了拼接字符串然后通過innerHTML來創建就好了。
但是真正做的時候,開始測試各個瀏覽器的時候,才發現情況遠沒有想的這么簡單
關于如何引入Flash
這大概是最基本的問題,其他的一切問題都是基于Flash可以正確引入到DOM中這個前提的。
最先的方式自然是使用adobe給出的官方方式,即objectembed //object的結構來嵌入一個Flash。根據各種資料,embed標簽用于Firefox,而object標簽用于IE,兩者合在一起,就是一相相對完美的方式。
但是事情絕對不會就這樣完結,這個時候號稱最先進最標準的Chrome瀏覽器過來插了一腳:當使用objectembed //object結構來嵌入Flash時,在Chrome中會出現Flash不顯示的問題。
關于這個問題,他必須有2個前提:
- 使用objectembed //object的結構引入Flash。
- 在object前,有一個元素有background-image。
當以上兩個條件都滿足時,如果打開這個頁面,特別是在本地打開,有一定機率會看不到Flash。但是Flash確實存在,甚至連Flash的聲音都可以聽到,僅僅是瀏覽器沒有將其繪制在屏幕之上。
由于該問題與網絡環境有著聯系,在本地特別容易重現,可以將這個頁面的源碼保存為一個htm文件,在本地打開,刷新幾次,應該就能看到這個問題了。
為了這個問題,最后決定推翻objectembed //object的DOM結構。因為object和embed兩者是獨立的,因此就在各瀏覽器之間測試了標簽的兼容性,得出的結果是embed標準可以被現有的幾乎所有瀏覽器支持,包括了IE、Firefox、Chrome和Opera。最后,也在這篇文章上對引入Flash的方式有了最終的確認,僅使用embed標簽足夠引入Flash。而在去除object標簽后,Chrome下的詭異問題也隨之消失了。
關于如何移除Flash
又是一個看上去很簡單的問題,最簡單地代碼自然是:
element.parentNode.removeChild(element);
看上去非常簡潔、有效,理論上幾乎不會出現問題的代碼,卻在Opera這小眾分子上倒下了。簡單來說,如果embed標簽帶有position: fixed;樣式,使用以上的代碼移除該元素,Opera不會對界面進行重新繪制,這導致Flash會在屏幕上留下一個殘影,保留被移除時播放的那一幀的畫面,只有在系統有重新繪制的行為(包括滾動、切換其他窗口等)時,才會消失。
可以通過使用Opera瀏覽器訪問這個頁面來查看這個問題。
對于這個問題,解決辦法也不難,在移除embed標簽之前,先將該標簽隱藏起來,并要求瀏覽器進行一次繪制,將隱藏的效果體現出來,隨后再移除即可:
element.style.display = 'none'; // 先隱藏起來
// 利用setTimeout,讓DOM有一次重繪的時間
setTimeout(function() {
element.parentNode.removeChild(element);
}, 0);
關于如何給Flash加鏈接
給圖片加鏈接很簡單,只需要外面套一層a元素即可,在HTML5中a元素的內容終于被定義為Flow Content,這使得a元素內部可以放置大部分元素。
但是如果在a元素里放embed元素呢?很遺憾,Flash作為外部插件,非常暴力地將a給滅了,鏈接完全起來到任何效果。
那么,就只能創建一個a元素,讓他浮動在Flash之上。但是這里就必須保證a元素和embed的大小相同,以免鏈接干擾到其他的元素。
對于除IE6以外的瀏覽器,都支持使用top / bottom以及left / right成對出現的樣式來定義其高度和寬度,因此解決該問題還是比較方便的,只需要一個容器即可:
a href="xxx" style="position: absolute; left: 0; right: 0; top: 0; bottom: 0;"/a
embed ... /
/div
但是還剩下IE6,對于IE6,因為a元素是絕對定位的,因此height: 100%;也是沒有效果的。在這里有2種方法來解決這個問題:
- 使用css expression,相當消耗資源,但是大小的確定十分精準。
- 保證外部容器有確切的高度,并使用overflow: hidden;的樣式,配合a元素一個非常大的height值來實現全容器的點擊監控。
鑒于css expression那人人避之唯恐不及的效率問題,最后選擇了后者:
a href="xxx" style="position: absolute; top: 0; width: 100%; height: 2000px;"/a
embed ... /
/div
這個方案在其他瀏覽器中同樣也是有效的。
最后,看到僅僅簡單地使用一個Flash,也存在這么多的問題,認為只要Flash存在就不需要推廣HTML5的開發者們,是不是還能堅持自己的想法呢?