中國人的習俗,沒過完正月十五就還是在過年,在這裡給園子你的朋友們拜個晚年了。
這幾天恰逢公司網站首頁需要改版,去年底公司“人員精簡”後,一個人得做多個人的活,忽然之間發覺擔子重了。這不, 本不是我工作范圍內的事情,不幸也讓我參與其中了,不幸中的幸事是這次BOSS交給我的任務,恰是我一直熱衷的前端開發任務。之前一直從事公司網站的後台管理程序開發,更多是在服務器端處理業務邏輯,一直沒有機會在我熱衷的前端開發上施展拳腳。實踐是檢驗真知的最好途徑,通過解決分派給我的實際任務正是一次難得的大檢驗,通過書本和各種資料學習許多零散的知識,卻未得機會將他們揉合在一起來次“綜合測驗”,呵呵。前面墨跡那麼多,都是壓抑久了惹得禍,呵呵。
我先來描述一下任務要求吧:公司網站首頁上有一張由五個球組成的JPG圖片,其作用是用來導航,點擊每個球上的文字後會打開相應信息的二級頁面,與該圖片相應的有一個幾乎一模一樣的Flash版本。而上司布置給我的任務之一就是:當客戶端浏覽器安裝了Flash文件播放器時,顯示Flash版導航,反之顯示JPG圖片導航。拿到任務後,考慮片刻,既是前端開發,當然要考慮浏覽器兼容問題,跨越浏覽器之間的鴻溝最好的辦法就是使用一種或多種成熟的JavaScript框架,很幸運的是恰好有一個非常成熟精巧的JS框架存在,名曰:SWFObject.js。
第一次接觸SWFObject.js是其V1.5,而這次我解決問題使用的是V2.1,兩者之間的使用上還是有些差別的。整體上給我的感覺是V2.1較之V1.5來說,是一次大躍進,V2.1無論從框架的源碼還是使用過程來說,都更加符合面向對象的JavaScript編程風格。
我將以一個探索JavaScript不久的研習者的視角,帶著您一起來體驗這趟“折騰”之旅,無論您是和我一樣的新手,還是已經能夠熟練編寫各種JS代碼的老手,望請手下留情,希望大家以文明的心態指出我思考中的短視和文字中的錯誤。
下面的代碼是我從SWFObject V1.5的一篇說明文檔( 如想進一步了解V1.5請點擊該鏈接即可)中改編而來的使用示例:
復制代碼代碼如下:
<html>
<title>DEMO</title>
<head>
<script type="text/javascript" src="swfobject_source.js"></script>
<script type="text/javascript">
var so = new SWFObject("http://www.pec365.com/Flash/20071113.swf", "mymovie", "304", "367", "7", "#FFFFFF");
so.write("flashcontent");
</script>
</head>
<body>
<form id="Form1">
<div id="flashcontent">
<a href="http://www.adobe.com/go/getflashplayer">
<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" border="0" />
</a>
</div>
</form>
</body>
</html>
如果您想簡要了解一下SWFObject()中的各個參數的含義,請參考說明文檔,再此不在復述。
我強烈建議您,把“V1.5使用示例”中的代碼拷貝到記事本中,並點擊SWFObject V1.5下載所需的V1.5框架的源文件, 解壓縮後找到swfobject_source.js(未壓縮版,壓縮版文件名是swfobject.js)文件,將記事本文件更名為demo.html後與swfobject_source.js文件放置於相同文件夾下即可,然後請您分別在IE6/IE7、fox、opera、safari、 navigator、chrome 等任意一款浏覽器下運行看看結果如何。
如果您按照我的建議操作了,應當發現顯示在頁面上的是這張圖 ,而非一個Flash文件,這是為什麼呢?如果您的PC上恰好安裝了IE系列的話,請按照以下步驟操作:點擊IE浏覽器圖標,找到工具欄上的“工具”菜單,選中的“Internet選項”, 在打開的窗口中點擊“高級”,找到“禁用腳本調試(Internet Explorer)”選項,將其前面方框中的勾選去掉,點擊“確定”。請在完成上述操作之後,再次浏覽demo.html頁面,是否會發現彈出一個錯誤提示框,其提示錯誤信息如下:“出現了運行時錯誤,是否需要進行調試。行:117 錯誤:'null'為空或不是對象。”
如果您恰好正在使用VS 2003/2005/2008系列的IDE做開發,那麼我想無需教您如何調試JavaScript代碼了,您可以var so = ……的上方打一個debugger,然後調試跟蹤進去,不停按F11後直到通過so.write()方法追蹤到swfobject_source.js文件的內部,您會發現傳遞給so.write(elementId)的實參"flashcontent"在document.getElementById("flashcontent")時值一直為null,這又是為什麼?發現問題所在了嗎?
呵呵,如果您還是一名對JavaScript了解不多的新手,那麼會和當時的我一樣頓時陷入迷惘之中,在經過多次的調試和修改代碼後, 我堅信自己編寫的JS代碼本身是不存在錯誤的,難道是外部加載的swfobject_source.js文件有問題,如果有問題,那問題究竟出在哪裡了?當時,我是這樣尋求解決錯誤的方法,我將上述代碼修改為以下示例:
復制代碼代碼如下:
<html>
<title>DEMO</title>
<head>
<script type="text/javascript">
// 執行一個匿名函數,和執行一個普通的函數沒有差別
(function() {
var flash = document.getElementById("flashcontent");
var msg = null;
window.onload = function() {
if ( flash ) {
msg = 'The element does exist.';
flash.innerHTML = msg;
} else {
msg = 'The element does not exist';
window.alert( msg );
}
};
})();
</script>
</head>
<body>
<form id="Form1">
<div id="flashcontent">
<a href="http://www.adobe.com/go/getflashplayer">
<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" _fcksavedurl=""http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif"" alt="Get Adobe Flash player" border="0" />
</a>
</div>
</form>
</body>
</html>
如果您執行了上述代碼就會發現,依舊發現顯示在頁面上的還是這張圖 ,並且彈出一個含有“The element does not exist"的警告框,看來問題並非出自外部加載的swfobject_source.js文件上。
如果您看到這裡,定會體驗我當時的懊惱,在稍微休息後,清醒下腦子回頭再看,才發現問題的本質出在“HTML DOM的加載”上。在一個頁面中,處於頁面頭部(即<head></head>之間)中的JS腳本以及從外部文件加載的JS文件會在HTML DOM 真正構造之前就執行了。因此這兩個地方執行的腳本並不能訪問還不存在的DOM。您應該知道真正的原因了,那就是示例1.1 中的JS代碼執行過程中,訪問了還未來得及構造的<div id="flashcontent">……</div>。
好了,看到這裡,還有最後一個步驟需要您親自動手操作一下,就是將上述代碼簡單的修改一下,采取一種並不優雅的方法解決
關於“HTML DOM的加載”的問題,到底是哪種方法呢,我想大家或許應該猜想到了,對,正是如下這種方式:
復制代碼代碼如下:
<html>
<title>DEMO</title>
<head>
<script type="text/javascript" src="swfobject_source.js"></script> _fcksavedurl=""swfobject_source.js"></script>"
</head>
<body>
<form id="Form1">
<div id="flashcontent">
<a href="http://www.adobe.com/go/getflashplayer">
<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" border="0" />
</a>
</div>
</form>
<script type="text/javascript">
var so = new SWFObject("http://www.pec365.com/Flash/20071113.swf", "mymovie", "304", "367", "7", "#FFFFFF");
so.write("flashcontent");
</script>
</body>
</html>
前面洋洋灑灑上千字,只是在描述我走了多少彎路,在解決問題的過程中遇見那些麻煩,從麻煩中解脫出來運用了那些學習的
知識,又從中學習了那些知識,雖然有點累贅之嫌,但是您是否如我一樣也有不一樣的收獲呢?