Javascript的調試利器:Firebug使用詳解(轉)
Posted on 2007-11-01 10:28 Edward's 閱讀(784) 評論(0) 編輯 收藏 所屬分類: javascriptJavascript的調試,是開發Web應用尤其是AJAX應用很重要的一環,目前對Javascript進行調試的工具很多,我比較喜歡使用的是Firebug。Firebug是Joe Hewitt開發的一套與Firefox集成在一起的功能強大的web開發工具,可以實時編輯、調試和監測任何頁面的CSS、HTML和JavaScript。
本文主要是為初學者介紹一下Firebug的基本功能與如何使用Firebug。由于本人水平與能力有限,在文章中的可能會有很多錯誤與遺漏,希望大家能諒解和指正!
<!--[if !supportLists]-->1、 <!--[endif]-->安裝
Firebug是與Firefox集成的,所以我們首先要安裝的事Firefox瀏覽器。安裝好瀏覽器后,打開瀏覽器,選擇菜單欄上的“工具”菜單,選擇“附加軟件”,在彈出窗口中點擊右下角的“獲取擴展”鏈接。在打開的頁面的search輸入框中輸入“firebug”。等搜索結果出來后點擊Firbug鏈接(圖1-1紅色圈住部分)進入Firebug的下載安裝頁面。
<!--[if !vml]--><!--[endif]-->
圖1-1
在頁面中點擊Install Now(圖1-2)按鈕。
<!--[if !vml]--><!--[endif]-->
圖1-2
在彈出窗口(圖1-3)中等待3秒后單擊“立即安裝”按鈕。
<!--[if !vml]--><!--[endif]-->
圖1-3
等待安裝完成后會單擊窗口(圖1-4)中的“重啟 Firefox”按鈕重新啟動Firefox。
<!--[if !vml]--><!--[endif]-->
圖1-4
當Firefox重啟完后我們可以在狀態欄最右邊發現一個灰色圓形圖標(<!--[if !vml]--><!--[endif]-->),這就表示Firebug已經安裝好了。灰色圖標表示Firebug未開啟對當前網站的編輯、調試和監測功能。而綠色(<!--[if !vml]-->
<!--[endif]-->)則表示Firebug已開啟對當前網站進行編輯、調試和監測的功能。而紅色圖標(<!--[if !vml]-->
<!--[endif]-->)表示已開啟對當前網站進行編輯、調試和監測的功能,而且檢查到當前頁面有錯誤,當前圖標表示有5個錯誤。
<!--[if !supportLists]-->2、 <!--[endif]-->開啟或關閉Firebug
單擊Firebug的圖標或者按F12鍵你會發現頁面窗口被分成了兩部分,上半部分是瀏覽的頁面,下半部分則是Firebug的控制窗口(圖2-1)。如果你不喜歡這樣,可以按CTRL+F12或在前面操作后單擊右上角的上箭頭按鈕,彈出一個新窗口作為Firebug的控制窗口。
<!--[if !vml]--><!--[endif]-->
圖2-1
從圖2-1中我們可以看到,因為我們開啟Firebug的編輯、調試和監測功能,所以目前只有兩個可以選擇的鏈接:“Enable Firebug”與“Enable Firebug for this web site”。如果你想對所有的網站進行編輯、調試和檢測,你可以點擊“Enable Firebug”開啟Firebug,則以后無論瀏覽任何網站,Firebug都處于活動狀態,隨時可以進行編輯、調試和檢測。不過一般的習慣我們只是對自己開發的網站進行編輯、調試和檢測,所以我們只單擊“Enable Firebug for this web site”開啟Firebug就行了。
開啟Firebug窗口(圖2-2)后,我們可以看到窗口主要有兩個區域,一個是功能區,一個是信息區。選擇功能區第二行的不同標簽,信息區的顯示會有不同,Options的選項也會不同,搜索框的搜索方式也會不同。
<!--[if !vml]--><!--[endif]-->
圖2-2
要關閉Firebug控制窗口單擊功能區最右邊的關閉圖標或按F12鍵就行了。如果要關閉Firebug的編輯、調試和監測功能,則需要單擊功能區最左邊的臭蟲圖標,打開主菜單,選擇“Disable Firebug”或“Disable Firebug for xxxxx”。
<!--[if !supportLists]-->3、 <!--[endif]-->Firebug主菜單
單擊功能區最左邊的臭蟲圖標可打開主菜單(圖3-1),其主要功能描述請看表1。
<!--[if !vml]--><!--[endif]-->
圖3-1
菜單選項
說明
Disable Firebug
關閉/開啟Firebug對所有網頁的編輯、調試和檢測功能
Disable Firebug for xxxxx
關閉/開啟Firebug對xxxxx網站的編輯、調試和檢測功能
Allowed Sites
設置允許編輯、調試和檢測的網站
Text Size:Increase text size
增大信息區域顯示文本的字號
Text Size:Decrease text size
減少信息區域顯示文本的字號
Text Size:Normal text size
信息區域以正常字體顯示
Options:Always Open in New Window
設置Firebug控制窗口永遠在新窗口打開
Show Preview tooltips
設置是否顯示預覽提示。
Shade Box Model
當前查看狀態為HTML,鼠標在HTML element標簽上移動時,頁面會相應在當前標簽顯示位置顯示一個邊框表示該標簽范圍。這個選項的作用是設置是否用不同顏色背景表示標簽范圍。
Firebug Website..
打開Firebug主頁。
Documentation..
打開Firebug文檔頁。
Discussion Group
打開Firebug討論組。
Contribute
打開捐助Firebug 頁面。
表1
<!--[if !supportLists]-->4、 <!--[endif]-->控制臺(Console)
單擊功能區第二欄的“Console”標簽可切換到控制臺(圖4-1)。控制臺的作用是顯示各種錯誤信息(可在Options里定義),顯示腳本代碼中內嵌的控制臺調試信息,通過命令行對腳本進行調試,通過單擊Profile對腳本進行性能測試。 控制臺分兩個區域,一個是信息區,一個是命令行,通過Options菜單的“Larger Command Line”可改變命令行位置。
<!--[if !vml]--><!--[endif]-->
圖4-1
Options菜單的選項請看表2。
菜單選項
說明
Show JavaScript Errors
顯示腳本錯誤。
Show JavaScript Warnings
顯示腳本警告。
Show CSS Errors
顯示CSS錯誤。
Show XML Errors
顯示XML錯誤。
Show XMLHttpRequests
顯示XMLHttpRequests。
Larger Command Line
將命令行顯示從控制窗口底部移動右邊,擴大輸入區域。
表2
單擊“Clear”按鈕可清除控制臺的控制信息。
<!--[if !supportLists]-->5、 <!--[endif]-->頁面源代碼查看功能
單擊功能區第二欄的“HTML”標簽可切換到源代碼查看功能(圖5-1)。雖然Firefox也提供了查看頁面源代碼的功能,但它顯示的只是頁面文件本身的源代碼,通過腳本輸出的HTML源碼是看不到。而Firebug則是所見即所得,是最終的源代碼。
<!--[if !vml]--><!--[endif]-->
圖5-1
我們來看一個例子,文件源代碼如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>簡單的例子</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<style>
#div1{background:red;width:100px;height:100px;}
#div2{background:blue;width:100px;height:100px;margin:10px;padding:10px;border:5px solid black;color:white;}
#div3{background:yellow;width:50px;height:50px;margin-left:25px;}
</style>
</head>
<body scroll="no">
<div id="div1">方塊一</div>
<div id="div2">方塊二</div>
<script>
document.getElementById('div1').innerHTML+='<div id="div3">方塊三</div>';
</script>
</body>
</html>
在例子中我們通過JavaScript在“div1”中加入了“div3”,在Firefox中查看源代碼你是看不到“div1”中包含有代碼“<div id="div3">
方塊三</div>
”的,但是Firebug中我們是可以看見的(圖5-2選中部分)。
<!--[if !vml]--><!--[endif]-->
圖5-2
從圖5-1中我們可以看到,信息區被分成了兩個部分,左邊是顯示源代碼,右邊是一個功能區,可以從這里查看到HTML Element中的CSS定義、布局情況和DOM結構。
從圖5-2中我們可以看到,源代碼按DOM結構分層次顯示的,通過層次折疊功能,我們就可以很方便分析代碼。在功能區的第一行還根據你的選擇,清晰的按子、父、根列出了當前源代碼的層次(圖5-2紅色部分),單擊各部分,則會即刻轉到該部分的源代碼。
<!--[if !vml]--><!--[endif]-->
圖5-3
在源代碼上移動鼠標,頁面就會出現一個半透明的方塊,指示當前鼠標所指源代碼的顯示區域,當選擇。在圖5-4中,鼠標正指向“div1”,而在頁面中“div1”的顯示區域上被一個半透明的方塊遮蓋了。
<!--[if !vml]--><!--[endif]-->
圖5-4
如果你把“Inspect”按鈕按下,功能正好相反,在頁面中移動鼠標,則當前顯示區域的源代碼會被加亮顯示出來。在圖5-5中,我們可以看到鼠標指針正指向“方塊二”,而在源代碼中可以看到,“方塊二”的源代碼“<div id="div2">
方塊二</div>
”已被加亮顯示(紅色部分)。如果你單擊某個顯示區域,則該區域的源代碼會被選中。
<!--[if !vml]--><!--[endif]-->
圖5-5
是不是很方便?方便是方便,但是我的源代碼很多,而且有些區域在頁面中不方便鼠標指定,怎么辦?沒關系,我們還有一個厲害武器,搜索功能。譬如我們知道某個HTML Element的ID是“div2”,但在層層疊疊的源代碼中不好找,在頁面中鼠標也很難找到,那我們就在功能區的搜索框中輸入“div2”,再看看源代碼區域,“div2”被加亮顯示出來了(圖5-6紅色部分)。在這個簡單的例子可能看不出很好的效果,大家可以嘗試一下把“div1”先折疊起來,然后在搜索框輸入“div3”,你可以看到“div1”會自動展開,并將“div3”加亮顯示,如果還覺得不夠理想,可以找一個源代碼比較多的例子測試一下。
<!--[if !vml]--><!--[endif]-->
圖5-6
除了通過按下“Inspect”按鈕,單擊顯示區域選擇源代碼,我們還可以通過單擊源代碼中的HTML標記(開始或結束標記都可以)來選擇。我們嘗試一下把鼠標移動到HTML標記,會發現鼠標指針變成了手的形狀,這說明我們可以通過單擊選擇該源代碼。選擇源代碼后,我們就可以通過右邊的功能區查看、編輯和調試它的CSS定義和盒子模型(CSS盒子模型請參閱相關說明,這里就不再贅述了),還有一個很好的功能就是當外部編輯器修改了源代碼(沒有刪除該源代碼,只是修改),我們在瀏覽器重新加載頁面后,選擇的源代碼不會改變,我們可以很方便的觀察源代碼的變化與效果。
有沒有經常為調試某個頁面效果在源代碼編輯器和瀏覽器之間切換,一次又一次的刷新而感到懊惱?有了Firebug你就不用再懊惱了。你可以直接在源代碼中進行編輯,然后查看效果。如果只是修改已經存在的屬性,例如要修改“div2”的內部文本,則直接將鼠標移動到文本上面,等鼠標指針換成“I”,單擊即可進行編輯了。其它已存在的屬性和屬性值也可以這樣直接進行編輯。如果要為某Element添加屬性,請將鼠標移動到該Element上,等光標變為“I”的時候,單擊鼠標右鍵,從菜單中選擇“New Attribute..”,在顯示的編輯框中輸入你要添加的屬性名稱就可以了。
<!--[if !vml]--><!--[endif]-->
圖5-7
<!--[if !vml]--><!--[endif]-->
圖5-8
我們嘗試一下為“div2”增加一個“onclick”屬性,單擊的結果是將“div2”的顯示文本修改為“單擊”。把光標移動到“div2”上,然后單擊鼠標右鍵,選擇“New Attribute..”(圖5-7),在編輯框中輸入“onclick”,最后按一下回車鍵(圖5-8),出現屬性值輸入框后,輸入“this.innerHTML=’單擊’”,回車后我們可以繼續添加下一個屬性,這次測試不需要,所以按ESC結束我們的輸入。我們來檢驗一下修改結果,單擊頁面“div2”的區域(圖5-9),“div2”的顯示文本已修改為“單擊”了,而源代碼也改變了。有沒有發現,“div2”被加亮顯示了?這又是Firebug的一個功能。只要我們通過頁面中的操作修改了Element的屬性,Firebug就會在源代碼中通過加亮的方式指示當前操作修改那些屬性值。譬如我們單擊某個鏈接修改了一個iframe里的src,那么這個src的屬性值就會被加亮顯示。 又譬如我們單擊某個鏈接修改了一個image里的圖像,那么它的src屬性值也會被加亮顯示。我們可以通過Options菜單里的“Highlight Changes”設置是否加亮顯示改變。而“Expand Changes”則是設置被改變的源代碼折疊起來看不見時展開讓它可見。而“Scroll Changes into view”則是源代碼很多,被改變的源代碼不在可視區域時,將被改變的源代碼滾動到可視區域。
<!--[if !vml]--><!--[endif]-->
圖5-9
有時候我們不單是要增加一兩個屬性,而是要做更多的修改,這怎么辦呢?很簡單,選擇你要更改Element,然后單擊功能區第一行的“Edit”按鈕或者直接將鼠標移動到要修改的Element上,單擊鼠標右鍵,選擇“Edit HTML..”,這時候,源代碼區域將切換到編輯狀態,你可以隨意的修改你選擇的源代碼了。我們嘗試修改一下“div2”,將被修改顯示文本修改回“方塊二”,我們選擇“div2”,然后單擊“Edit”按鈕(圖5-10),將顯示文本修改回“方塊二”,然后再次單擊“Edit”按鈕退出編輯狀態,如果要放棄修改,可以按ESC鍵退出。因為是所見即所得的,所以我們在修改的時候,頁面會同時刷新顯示。
<!--[if !vml]--><!--[endif]-->
圖5-10
如果要修改Element的CSS定義怎么辦?很簡單,選擇該Element,然后在右邊的窗口選擇“Style”標簽,這里顯示的就是當前Element的CSS定義了。我們在這里可以對CSS定義進行添加、編輯、刪除、禁止等操作。我們嘗試一下把“div2”的背景色禁止了看看。將鼠標移動到“background”這行(圖5-11),我們可以看到在這行的最右邊會有一個灰色的禁止圖標,只要單擊這個禁止圖標,就可以禁止了這個CSS屬性了。我們單擊這個圖標看看效果,頁面中的“div2”已經變成白色背景了,而禁止圖標也變成紅色,而文本會則變成灰色(圖5-12),這說明已經禁止了“background”了。當然了,這個操作也可以通過鼠標右鍵的“Disable XXXXX”來實現(XXXXX表示當前選擇的CSS屬性)。我們再次單擊禁止圖標,恢復“background”屬性。我們這次要把“background”的顏色由藍色(blue)修改為綠色(green)。我們把鼠標移動到“background”屬性值“blue”上(圖5-13)。怎么會出現一個藍色背景的方框?這是Firebug提供背景預覽功能,讓我們很直觀的知道當前背景是什么。如果背景是圖片的話,顯示的將是背景圖片的縮略圖。繼續我們的操作,單擊屬性值,在出現的編輯框中將“blue”修改為“green”。好了,背景已經修改為綠色了。現在的顯示文本是左對齊的,我想讓它居中對齊,這需要在CSS里加一個“text-align”的屬性,值為“center”。請在CSS上單擊鼠標右鍵,在菜單中選擇“New Property..”,在編輯框中輸入“te”,Firebug已通過自動完成功能幫我們輸入“text-align”了(圖5-14),按Tab鍵或回車,在屬性值中我們輸入“c”,Firebug再次幫我們自動完成了“center”(圖5-15),按Tab鍵或回車完成輸入,如果不需要繼續輸入新屬性,按ESC或單擊鼠標取消輸入。文本“方塊二”現在已經居中顯示了。如果忘記了某個屬性值有那些選項怎么辦?不要緊,在輸入屬性值的時候可以通過上、下箭頭選擇我們需要的屬性值。
在“Style”標簽里我們可以選擇“Options”菜單里的“Show Computed Style”查看瀏覽器默認的風格定義。
<!--[if !vml]--><!--[endif]-->
圖5-11
<!--[if !vml]--><!--[endif]-->
圖5-12
<!--[if !vml]--><!--[endif]-->
圖5-13
<!--[if !vml]--><!--[endif]-->
<!--[if !vml]--><!--[endif]-->
圖5-14
圖5-15
頁面設計中,我們有時候最頭疼的是什么?是盒子模型!為了調整一個Element的margin、border、padding和相對位置,我們往往需要花很多工夫去修改源代碼,然后刷新頁面查看效果。有了Firebug,你就可以輕松應對了。我們將右邊的區域切換到“Layout”標簽(圖5-16),你會看到一個盒子模型,里面從外到里通過不同的線和顏色劃分出了offset、margin、border、padding和內容五個區域,里面4個區域在每個邊上都有1個數值,表示該方向上的調整值。我們先在左邊選擇“div2”,然后把鼠標分別移動到“Layout”里的不同區域(圖5-17),然后留意一下頁面,頁面在頂部多了一條水平標尺,在左邊多一條垂直標尺,而4條實線指示出了當前鼠標指示的區域實際位置,通過與標尺的交點可以知道該區域離頁面顯示區域左上角的偏移量(單位是px),當然我們也可以通過layout中的數字計算出這些偏移量。在圖中,我們還可以看到,在內容區域的外面還有3個不同顏色的區域,它們從里到外用不同顏色表示了padding、border、margin的位置和偏移量。只要將鼠標移動到不同區域,頁面中的4條實線也會改變位置,指示出頁面中相應的區域。我們還可以通過修改Layout中的數值,對顯示效果進行調整。例如我們要將“div2”的內容顯示區域擴大到200×200,將鼠標移動最左邊的100上,光標變成“I”后,單擊鼠標,然后在輸入框中輸入200,按回車可繼續修改高度值,輸入200,回車后完成修改。頁面中的“div2”區域已經擴展到200×200了,而源代碼也增加了“style="width: 200px; height: 200px;"”(圖5-18)。我們切換標簽到“Style”,會發現多了“element.style {height:200px;width:200px;}”(圖5-19),而CSS定義里面的高度和寬度都劃了橫線,表示不起作用了,“element.style”表示直接定義在Element源代碼上的CSS屬性。有時候某些Element會有相同的屬性,也有自己特殊的屬性,而特殊的屬性想寫在Element的源代碼上,就可以在Style里單擊鼠標右鍵選擇“Edit Element Style..”進行添加。如果有興趣的話,大家可以嘗試修改“Layout”里的其它屬性值,看看頁面的變化,這里我就不再一一說明了。
如果不想在頁面中顯示標尺和4條實線,可以不選擇“Options”菜單里的“Show Rules and Guides”。
<!--[if !vml]--><!--[endif]-->
圖5-16
<!--[if !vml]--><!--[endif]-->
圖5-17
<!--[if !vml]--><!--[endif]-->
圖5-18
<!--[if !vml]--><!--[endif]-->
圖5-19
在源代碼顯示區域我們還可以通過鼠標右鍵復制源代碼和顯示內容,這里就不一一說明了。DOM的說明請看查看DOM結構一節,兩者是一樣的。在源代碼區域中如果覺得源代碼顯示太密,可以將“Options”菜單里的“Show White Space”選項打開,每個源代碼塊之間會用空白行隔離。如果要查看源代碼的注釋內容,請將“Options”菜單里的“Show Comments”選項打開。
這里要提醒大家一下,在HTML里調試出正確的源代碼和CSS后,別忘記將源代碼和CSS的修改結果復制到你的源代碼文件中,不然你的調試結果在頁面刷新后會付之東流。切記!切記!
<!--[if !supportLists]-->6、 <!--[endif]-->查看CSS定義
將功能區第二行的標簽切換到“CSS”,在這里我們可以查看頁面中所有的CSS定義,包括鏈接的CSS文件。通過功能區的文件選擇按鈕可以選擇不同的含有CSS的文件(圖6-1紅色圈住部分)。
<!--[if !vml]--><!--[endif]-->
圖6-1
CSS的定義的編輯這里就不再說明了,這個可以參考HTML的“Style”操作。
“Edit”按鈕功能和HTML的“Edit”功能類似。
<!--[if !supportLists]-->7、 <!--[endif]-->腳本調試
將功能區第二行的標簽切換到“Script”,在這里我們可以對頁面中所有的腳本進行調試,包括鏈接的腳本。和CSS一樣,可以通過文件選擇按鈕選擇不同的腳本文件。
如果要在腳本中設置一個斷點,可以單擊行號旁邊的空白區域,這時會出現一個紅色的點表示在這里設置了斷點(圖7-1),當腳本運行到此會停止運行,等待你的操作。在右邊的小窗口將標簽切換到“Breakpoints”可以查看我們設置的所有斷點(圖7-2),單擊左上角的checkbox可以讓斷點不起作用,如果要刪除斷點可以單擊右上角的刪除圖標。通過“Options”菜單的“Disable All Breakpoints”可暫時禁止所有斷點,而“Remove All Breakpoints”可刪除所有斷點。在斷點標記的紅點上單擊右鍵還可以設置斷點條件,在符合條件的時候才會停止腳本的執行。
<!--[if !vml]--><!--[endif]-->
圖7-1
<!--[if !vml]--><!--[endif]-->
圖7-2
下面我們來嘗試一下斷點的功能。首先在測試頁腳本里增加一個test的函數,函數的主要操作是運行一個1000次的循環,將循環的參數值顯示在“div2”里:
function test(){
for(var i=0;i<1000;i++){
document.getElementById('div2').innerHTML=i;
}
}
在“div2”里增加一個“onclick”屬性,單擊后執行test:
<div id="div2" onclick='test()'>
方塊二</div>
刷新頁面,然后在“for(var i=0;i<1000;i++){
”這行上設置一個斷點,并設置條件為“i=100”(圖7-3),然后單擊“div2”開始執行函數test。
<!--[if !vml]--><!--[endif]-->
圖7-3
當腳本停下來后,我們將鼠標移動到變量“i”上,這時會出現一個小方框,里面有一個數值,這就是變量“i“的當前值(圖7-4)。在腳本調試的時候,你可以通過這個方法很方便的了解到當前變量的值。你還可以通過右邊窗口的“Watch”標簽查看到“i”的值(圖7-5)。
<!--[if !vml]--><!--[endif]-->
圖7-4
<!--[if !vml]--><!--[endif]-->
圖7-5
在“Watch”標簽窗口我們可以通過“Options”菜單選擇查看用戶自定義屬性(Show User-defined Properties)、用戶自定義函數(Show User-defined Functions)、DOM屬性(Show DOM Properties)、DOM函數(Show DOM Functions)和DOM常數(Show DOM Constants)。我們還可以通過單擊“New watch expression…”(圖7-6淡黃色背景部分)加入自己想跟蹤的內容。例如我們想跟蹤一下“div2”的顯示內容,就可以單擊“New watch expression…”,加入“document.getElementById('div2').innerHTML”,輸入中可通過TAB鍵自動完成關鍵字的輸入(圖7-7)。如果不想跟蹤了,可單擊最右邊的刪除圖標取消跟蹤。
<!--[if !vml]--><!--[endif]-->
圖7-6
<!--[if !vml]--><!--[endif]-->
圖7-7
腳本在斷點停止后,我們就可以利用搜索框旁的4個跟蹤按鈕進行代碼跟蹤了(圖7-7)。第一按鈕是繼續運行程序,不再執行跟蹤,快捷鍵是F8。第二個按鈕是單步執行方式,每次執行一條語句,該方式在遇到函數調用時不進入調用函數內部進行跟蹤,快捷鍵是F10。第三個按鈕也是單步執行方式,每次執行一條語句,但它遇到函數調用時會進入調用函數內部進行跟蹤,快捷鍵是F11。當你進入調用函數內,想馬上跳出來時,可以單擊第四個按鈕,該按鈕沒有快捷鍵。
搜索框的作用和HTML源代碼查看是一樣的,不過有一個不同,就是輸入“#n”(n≥1),可以直接跳到腳本的第n行。
當執行腳本在“console”標簽內顯示一個錯誤,而錯誤的提示行左邊出現一個暗紅色的圓點時(圖7-8),我們可以單擊改紅點在該行設置一個斷點。
<!--[if !vml]--><!--[endif]-->
圖7-8
我們可以通過“Script”標簽的“Options”菜單的“Break on All Errors”選項設置每當腳本發生錯誤時就中斷腳本,進入調試狀態。
有時候一個函數隨機出現錯誤,你不可能每次調用都去跟蹤一次,而產生錯誤的原因很可能是傳遞的參數錯誤,這時你可以通過跟蹤函數調用的功能去檢查每次調用函數時的參數情況。操作在函數腳本內單擊鼠標右鍵,在菜單中選擇“Log Calls to xxxxx”(xxxxx為函數名),然后可在“console”標簽中可查看函數調用情況。
<!--[if !supportLists]-->8、 <!--[endif]-->查看DOM結構
將功能區第二行的標簽切換到“DOM”可俺層次查看整個頁面的DOM結構。通過“Options”菜單可自定義選擇查看用戶自定義屬性(Show User-defined Properties)、用戶自定義函數(Show User-defined Functions)、DOM屬性(Show DOM Properties)、DOM函數(Show DOM Functions)或DOM常數(Show DOM Constants)等內容。
通過雙擊你可以修改DOM里面的屬性值。
<!--[if !supportLists]-->9、 <!--[endif]-->查看網絡狀況
作為開發人員,是否會經常聽到老板或客戶抱怨頁面下載太慢了?于是你就懷疑是否腳本太多了?忘記壓縮圖片了?服務器太慢了?網絡太慢?確實是頭疼的事情。有了Firebug,你就可以很容易的對這個問題進行分析和判斷了。請將Firebug的當前標簽切換到“Net”(圖9-1)。
<!--[if !vml]--><!--[endif]-->
圖9-1
<!--[if !vml]--><!--[endif]-->
圖9-2
從圖中我們可以看到,頁面中每一個下載文件都用一個灰色條表示它相對其它文件是從什么時候開始下載的,下載時間是多少。在底部我們看到頁面發送了多少個請求,下載總量是多少,有多少是有緩存的,下載總共花費了多少時間等信息。
如果只想了解某一樣文件的下載情況,你可以單擊功能區第一欄的文件分類按鈕過濾文件(圖9-2紅色圈住區域1)。
將鼠標在文件中移動,如果是圖片,我們可以看到圖片的縮略圖(圖9-2紅色圈住區域3)。
如果顯示為紅色的文件名,則表示該文件在服務器中不存在,不能下載,這樣你就要檢查一下文件的路徑是否正確或者是否上傳了該文件(圖9-2紅色圈住區域2)。
我們可以展開某個文件,查看它的HTTP頭信息和返回結果的信息。如果請求的是一個動態頁面或XMLHttpRequest,則還可以查看提交的變量。通過查看提交的變量和返回信息,我們可以很方便的調試程序是否正確提交了需要的變量和返回了正確的數據。例如從圖36中,我們可以看到向“topics-remote.php”發送了一個請求,提交的參數有“_dc”、“callback”、“limit”和“start”四個,值分別為“1188637444000”、“stcCallback1001”、“25”與“0”,從這里我們可以很方便的知道我們腳本操作提交的參數是否正確。切換到“Response”頁可以看到返回的結果(圖9-3),在這里你可以對返回結果進行檢查。如果你感覺在這里查看結果很亂,你可以單擊鼠標右鍵,在彈出菜單中選擇“Copy Response body”復制結果到編輯器查看,你還可以選擇“Open in New Tab”打開一個新標簽瀏覽。
<!--[if !vml]--><!--[endif]-->
圖9-3
通過右鍵菜單你可以復制文件地址(Copy Location)、HTTP請求頭信息(Copy Request Headers)和HTTP響應頭信息(Copy Response Headers)。
如果不想使用該功能,可以選擇Options菜單的“Disable Network Monitoring”關閉該功能。
<!--[if !supportLists]-->10、 <!--[endif]-->命令行調試
在“Console”標簽了有一個命令行工具,我們可以在這里運行一些腳本對頁面進行調試。
我們在命令行中輸入“document.getElementById('div2').innerHTML”看看效果(圖10-1),別忘了用TAB鍵實現快速輸入關鍵字。在信息區顯示了當前“div2”的顯示內容。
<!--[if !vml]--><!--[endif]-->
圖10-1
要輸入“document.getElementById”是不是覺得很麻煩?這里有一個簡單的辦法,用“$”符號代替“document.getElementById”,我們再在命令行中輸入“$('div2').innerHTML”,然后看看結果,是一樣(圖10-2)。
<!--[if !vml]--><!--[endif]-->
圖10-2
當你通過“Inspect”鎖定了一些HTML Element時,你可以通過“$1”來訪問最后一個Element,依次類推,我們可以通過“$n”(n>1)訪問依次倒序訪問鎖定的Element。
我們來實踐一下,刷新一下測試頁面,然后按下“Inspect”按鈕,鼠標單擊“方塊二”,然后在按下“Inspect”按鈕,單擊“方塊一”。將firebug窗口切換回“Console”標簽,然后輸入“$1”,回車后再輸入“$2”,查看一下結果(圖10-3),正是我們用鎖定過的Element。
<!--[if !vml]--><!--[endif]-->
圖10-3
在命令行還可以通過“$$(HTML 標記)”返回一個Element數組。我們在測試頁輸入“$$(‘div’)”看看(圖10-4)。我們再輸入“$$(‘div’)[0]”看看(圖10-5)。是不是很便于我們對HTML進行調試。
<!--[if !vml]--><!--[endif]-->
圖10-4
<!--[if !vml]--><!--[endif]-->
圖10-5
命令行的所有特殊函數請看表3:
命令
說明
$(id)
通過id返回Element。
$$(selector)
通過CSS選擇器返回Element數組。
$x(xpath)
通過xpath表達式返回Element數組。
dir(object)
列出對象的所有屬性,和在DOM標簽頁查看該對象的是一樣的。
dirxml(node)
列出節點的HTML或XML的源代碼樹,和在HTML標簽頁查看改節點一樣。
cd(window)
默認情況下,命令行相關的是頂層window對象,使用該命令可切換到frame里的window獨享。
clear()
清空信息顯示區,和單擊按鈕Clear功能一樣。
inspect(object[, tabName])
監視一個對象。tabName表示在那個標簽頁對該對象進行監視,可選值為“html”、“css”、“script”和“dom”。
keys(object)
返回由對象的屬性名組成的數組。
values(object)
返回由對象的屬性值組成的數組。
debug(fn)
在函數的第一行增加一個斷點。
undebug(fn)
移除在函數第一行的斷點。
monitor(fn)
跟蹤函數fn的調用。
unmonitor(fn)
不跟蹤函數fn的調用。
monitorEvents(object[, types])
跟蹤對象的事件。Types的可選值為“composition”、 “contextmenu”、 “drag”、 “focus”,、“form”、“key”、 “load”、“mouse”、“mutation”、“paint”、“scroll”、“text”、“ui”和“xul”。
unmonitorEvents(object[, types])
不跟蹤對象的事件。Types的可選值為“composition”、 “contextmenu”、 “drag”、 “focus”,、“form”、“key”、 “load”、“mouse”、“mutation”、“paint”、“scroll”、“text”、“ui”和“xul”。
profile([title])
開始對腳本進行性能測試,可選參數title將作為測試結果的標題。
profileEnd()
結束腳本性能測試。
表3
命令行有命令記憶功能,可通過上、下箭頭鍵選擇已經輸入過的命令。
<!--[if !supportLists]-->11、 <!--[endif]-->在腳本文件中加入調試命令
有沒有對腳本調試中經常需要alert感到厭煩?有了Firebug,你就可以放下alert了,因為Firebug有功能比alert更強大的console.log。
先讓我們來認識一下console.log,在測試文件腳本區域我們輸入一下代碼:
console.log('Hello');
刷新一下頁面,將firebug切換到“console”標簽看看(圖11-1),在信息區顯示出了我們要輸出的信息“Hello”。當然了,單憑這個就說console.log有點夸大,我們修改一下test函數,把“document.getElementById('div2').innerHTML=i;”修改為:
console.log('當前的參數是:%d',i);
<!--[if !vml]--><!--[endif]-->
圖11-1
刷新頁面后看看結果(圖11-2)。是不是挺不錯的?console.log可以象c語言的printf一樣實現格式化輸出。我們再在腳本區加入一個語句:
console.log(2,4,window,test,document);
<!--[if !vml]--><!--[endif]-->
圖11-2
刷新頁面后看看結果(圖11-3)。console.log可以連續輸出多個對象,而且如果對象是DOM、函數,還可以直接點擊去到該對象。
<!--[if !vml]--><!--[endif]-->
圖11-3
如果你覺得console.log輸出的文本太單調,不能表示出不同的信息,那么你可以通過console.debug、 console.info、 console.warn和console.error來代替console.log,這些函數分別會用不同的背景顏色和文字顏色來顯示信息。
我們來看看測試一下這些函數的輸出,在腳本中加入:
console.debug('This is console.debug!');
console.info('This is console.info!');
console.warn('This is console.warn!');
console.error('This is console.error!');
刷新頁面看看結果(圖11-4)。
<!--[if !vml]--><!--[endif]-->
圖11-4
有時候,為了更清楚方便的查看輸出信息,我們可能需要將一些調試信息進行分組輸出,那么可以使用console.group來對信息進行分組,在組信息輸出完成后用console.groupEnd結束分組。我們測試一下把剛才的4個輸出作為一個分組輸出,修改代碼為:
console.group('開始分組:');
console.debug('This is console.debug!');
console.info('This is console.info!');
console.warn('This is console.warn!');
console.error('This is console.error!');
console.groupEnd();
刷新頁面看看結果(圖11-5)。在console.group中,我們還可以加入一個組標題“開始分組:
”。如果需要,我們還可以通過嵌套的方式,在組內再分組。
<!--[if !vml]--><!--[endif]-->
圖11-5
有時候,我們需要寫一個for循環列出一個對象的所有屬性或者某個HTML Element下的所有節點,有了firebug后,我們不需要再寫這個for循環了,我們只需要使用console.dir(object)或console.dirxml(element)就可以了。
在測試頁中加入代碼測試一下:
console.dir(document.getElementById('div1'));
console.dirxml(document.getElementById('div1'));
結果請看圖11-6和圖11-7。
<!--[if !vml]--><!--[endif]-->
圖11-6
<!--[if !vml]--><!--[endif]-->
圖11-7
是否想知道代碼的運行速度?很簡單,使用console.time和console.timeEnd就可以。
修改一下test函數的代碼,測試一下運行1000次循環需要多少時間:
function test(){
console.time('test');
for(var i=0;i<1000;i++){
document.getElementById('div2').innerHTML=i;
//console.log('當前的參數是:%d',i);
}
console.timeEnd('test');
}
刷新頁面,單擊“方塊二”,看看結果(圖11-8)。在這里要注意的是console.time和console.timeEnd里的參數要一致才會有正確的輸出,而該參數就是信息的標題。
<!--[if !vml]--><!--[endif]-->
圖11-8
是否想知道某個函數是從哪里調用的?console..trace可幫助我們進行追蹤。在test函數的結尾加入:
console.trace();
刷新頁面,單擊“方塊二”,看看結果(圖11-9)。結果顯示是在坐標(97,187)的鼠標單擊事件執行了test函數,而調用的腳本是在simple.html文件里的第1行。因為是在HTML里面的事件調用了test函數,所以顯示的行號是第1行。如果是腳本,則會顯示調用腳本的行號,通過單擊可以直接去到調用行。
<!--[if !vml]--><!--[endif]-->
圖11-9
如果想在腳本某個位置設置斷點,可以在腳本中輸入“debugger”作為一行。當腳本執行到這一行時會停止執行等待用戶操作,這時候可以通過切換到“Script”標簽對腳本進行調試。
Firebug還有其它的一些調試函數,這里就不一一做介紹,有興趣可以自己測試。表4是所有函數的列表:
函數
說明
console.log(object[, object, ...])
向控制臺輸出一個信息。可以輸入多個參數,輸出將已空格分隔各參數輸出。
第一參數可以包含格式化文本,例如:
console.log(‘這里有%d個%s’,count,apple);
字符串格式:
%s :字符串。
%d, %i:數字。
%f: 浮點數。
%o -超鏈接對象。
console.debug(object[, object, ...])
向控制臺輸出一個信息,信息包含一個超鏈接鏈接到輸出位置。
console.info(object[, object, ...])
向控制臺輸出一個帶信息圖標和背景顏色的信息,信息包含一個超鏈接鏈接到輸出位置。
console.warn(object[, object, ...])
向控制臺輸出一個帶警告圖標和背景顏色的信息,信息包含一個超鏈接鏈接到輸出位置。
console.error(object[, object, ...])
向控制臺輸出一個帶錯誤圖標和背景顏色的信息,信息包含一個超鏈接鏈接到輸出位置。
console.assert(expression[, object, ...])
測試一個表示是否為true,如果為false,提交一個例外信息到控制臺。
console.dir(object)
列出對象的所有屬性。
console.dirxml(node)
列出HTML或XML Element的XML源樹。
console.trace()
輸出堆棧的調用入口。
console.group(object[, object, ...])
將信息分組再輸出到控制臺。通過console.groupEnd()結束分組。
console.groupEnd()
結束分組輸出。
console.time(name)
創建一個名稱為name的計時器,計算代碼的執行時間,調用console.timeEnd(name)停止計時器并輸出執行時間。
console.timeEnd(name)
停止名稱為name的計時器并輸出執行時間。
console.profile([title])
開始對腳本進行性能測試,title為測試標題。
console.profileEnd()
結束性能測試。
console.count([title])
計算代碼的執行次數。titile作為輸出標題。
表4
<!--[if !supportLists]-->12、 <!--[endif]-->在IE中使用Firebug
Firebug是Firefox的一個擴展,但是我習慣在IE中調試我的頁面怎么辦?如果在頁面腳本中加入console.log()將調試信息寫到Friebug,在IE中肯定是提示錯誤的,怎么辦?不用擔心,Frirebug提供了Frirbug Lite腳本,可以插入頁面中模仿Firebug控制臺。
我們可以從一下地址下載firebug lite:
http://www.getfirebug.com/releases/firebuglite1.0-b1.zip
然后在頁面中加入:
<script language="javascript" type="text/javascript" src="/路徑/firebug.js"></script>
如果你不想在IE中模仿Friebug控制臺,只是不希望console.log()腳本出現錯誤信息,那么在頁面中加入一下語句:
<script language="javascript" type="text/javascript" src="/路徑/firebugx.js"></script>
如果你不想安裝Firebug Lite,只是想避免腳本錯誤,那么可以在腳本中加入以下語句:
if (!window.console || !console.firebug)
{
var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
"group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
window.console = {};
for (var i = 0; i < names.length; ++i)
window.console[names[i]] = function() {}
}
我們將firebug.js加入到測試頁面中,然后打開IE,加載頁面。頁面加載完成后,我們按下F12鍵就可以打開控制臺了。每次頁面刷新后,你都要按F12鍵打開控制臺,是不是很煩?如果不想那么,就在html標簽中加入“debug=’true’”,例如:
<html debug=
"true">
在Friebug Lite中也有命令行,但是功能沒那么強。
<!--[if !supportLists]-->13、 <!--[endif]-->快捷鍵和鼠標操作
全局操作
打開Firebug窗口
F12
關閉Firebug窗口
F12
在新窗口打開Firebug
Ctrl+F12
往前切換標簽
Ctrl+`
將光標移到命令行
Ctrl+Shift+L
將光標移到搜索框
Ctrl+Shift+K
進入Inspect模式
Ctrl+Shift+C
進行JavaScript性能測試
Ctrl+Shift+P
重新執行最后一條命令行命令
Ctrl+Shift+E
HTML標簽
編輯屬性
單擊屬性名或值
編輯文本節點
單擊文本
編輯Element
雙擊Element標記
移到路徑里的下一個節點
Ctrl+.
移到路徑里的上一個節點
Ctrl+,
HTML編輯
完成編輯
Return
取消編輯
Esc
移到下一個區域
Tab
移到上一個區域
Shift+Tab
HTML Inspect 模式
取消Inspect
Esc
Inspect 父節點
Ctrl+Up
Inspect 子節點
Ctrl+Down
Script標簽
繼續運行
F5
Ctrl+/
單步執行(Step Over)
F10
Ctrl+'
單步執行(Step Into)
F11
Ctrl+;
退出函數(Step Out)
Shift+F11
Ctrl+Shift+;
設置斷點
單擊行號
禁止斷點
在行號上Shift+Click
編輯斷點條件
在行號上Right-Click
運行到當前行
在行號上Middle-Click
在行號上Ctrl+Click
移到堆棧中的下一個函數
Ctrl+.
移到堆棧中的上一個函數
Ctrl+,
將焦點切換到Scripts菜單
Ctrl+Space
將焦點切換到Watch編輯
Ctrl+Shift+N
DOM 標簽
編輯屬性
雙擊在空白
移到路徑中下一個對象
Ctrl+.
移到路徑中上一個對象
Ctrl+,
DOM 和Watch編輯
結束編輯
Return
取消編輯
Esc
自動完成下一個屬性
Tab
自動完成上一個屬性
Shift+Tab
CSS標簽
編輯屬性
單擊屬性
插入新屬性
雙擊空白處
移動焦點到Style Sheets菜單
Ctrl+Space
CSS編輯
完成編輯
Return
取消編輯
Esc
移到下一個區域
Tab
移到上一個區域
Shift+Tab
按步長1增加數值
Up
按步長1減少數值
Down
按步長10增加數值
Page Up
按步長10減少數值
Page Down
自動完成下一個關鍵字
Up
自動完成上一個關鍵字
Down
Layout標簽
編輯值
單擊值
Layout編輯
完成編輯
Return
取消編輯
Esc
移到下一個區域
Tab
移到上一個區域
Shift+Tab
按步長1增加數值
Up
按步長1減少數值
Down
按步長10增加數值
Page Up
按步長10減少數值
Page Down
自動完成下一個關鍵字
Up
自動完成上一個關鍵字
Down
命令行 (小)
自動完成上一個屬性
Tab
自動完成下一個屬性
Shift+Tab
執行
Return
Inspect結果
Shift+Return
打開結果鼠標右鍵菜單
Ctrl+Return
命令行 (大)
執行
Ctrl+Return
<!--[if !supportLists]-->13、 <!--[endif]-->總結
真是意想不到,Firebug居然有那么多好功能居然是我不知道。通過寫本篇文章,才認真的了解和學習了一次Firebug,越學越感覺到它的威力。不過我學的也只是皮毛,還有更多的功能和技巧需要在平時的使用中慢慢積累,因此這篇文章只是一個簡單的介紹,還有很多東西是沒有涉及到的,而且因為我本身水平與能力有限,所以文中會有很多錯誤與遺漏,希望大家能多多諒解與指正!多謝!
例子最終源代碼:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html debug='true'>
<head>
<title>簡單的例子</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<style>...
#div1{...}{background:red;width:100px;height:100px;}
#div2{...}{background:blue;width:100px;height:100px;margin:10px;padding:10px;border:5px solid black;color:white;}
#div3{...}{background:yellow;width:50px;height:50px;margin-left:25px;}
</style>
<script language="javascript" type="text/javascript" src="firebug/firebug.js"></script>
</head>
<body scroll="no">
<div id="div1">方塊一</div>
<div id="div2" onclick='test()'>方塊二</div>
<script>...
document.getElementById('div1').innerHTML+='<div id="div3">方塊三</div>';
/**//* console.log('Hello');
console.log(2,4,window,test,document);
console.group('開始分組:');
console.debug('This is console.debug!');
console.info('This is console.info!');
console.warn('This is console.warn!');
console.error('This is console.error!');
console.groupEnd();*/
// console.dir(document.getElementById('div1'));
// console.dirxml(document.getElementById('div1'));
function test()...{
console.time('test');
for(var i=0;i<1000;i++)...{
document.getElementById('div2').innerHTML=i;
//console.log('當前的參數是:%d',i);
}
console.timeEnd('test');
console.trace();
}
</script>
</body>
</html>