Javascript的調(diào)試,是開發(fā)Web應(yīng)用尤其是AJAX應(yīng)用很重要的一環(huán),目前對Javascript進(jìn)行調(diào)試的工具很多,我比較喜歡使用的是Firebug。Firebug是JoeHewitt開發(fā)的一套與Firefox集成在一起的功能強(qiáng)大的web開發(fā)工具,可以實時編輯、調(diào)試和監(jiān)測任何頁面的CSS、HTML和JavaScript。
1、安裝
圖1-1
在頁面中點擊Install Now(圖1-2)按鈕。
圖1-2
在彈出窗口(圖1-3)中等待3秒后單擊“立即安裝”按鈕。
圖1-3
等待安裝完成后會單擊窗口(圖1-4)中的“重啟 Firefox”按鈕重新啟動Firefox。
圖1-4
當(dāng)Firefox重啟完后我們可以在狀態(tài)欄最右邊發(fā)現(xiàn)一個灰色圓形圖標(biāo)(
2、開啟或關(guān)閉Firebug
單擊Firebug的圖標(biāo)或者按F12鍵你會發(fā)現(xiàn)頁面窗口被分成了兩部分,上半部分是瀏覽的頁面,下半部分則是Firebug的控制窗口(圖2-1)。如果你不喜歡這樣,可以按CTRL+F12或在前面操作后單擊右上角的上箭頭按鈕,彈出一個新窗口作為Firebug的控制窗口。
圖2-1
從圖2-1中我們可以看到,因為我們開啟Firebug的編輯、調(diào)試和監(jiān)測功能,所以目前只有兩個可以選擇的鏈接:“EnableFirebug”與“Enable Firebug for this website”。如果你想對所有的網(wǎng)站進(jìn)行編輯、調(diào)試和檢測,你可以點擊“EnableFirebug”開啟Firebug,則以后無論瀏覽任何網(wǎng)站,F(xiàn)irebug都處于活動狀態(tài),隨時可以進(jìn)行編輯、調(diào)試和檢測。不過一般的習(xí)慣我們只是對自己開發(fā)的網(wǎng)站進(jìn)行編輯、調(diào)試和檢測,所以我們只單擊“Enable Firebug for this web site”開啟Firebug就行了。
開啟Firebug窗口(圖2-2)后,我們可以看到窗口主要有兩個區(qū)域,一個是功能區(qū),一個是信息區(qū)。選擇功能區(qū)第二行的不同標(biāo)簽,信息區(qū)的顯示會有不同,Options的選項也會不同,搜索框的搜索方式也會不同。
圖2-2
要關(guān)閉Firebug控制窗口單擊功能區(qū)最右邊的關(guān)閉圖標(biāo)或按F12鍵就行了。如果要關(guān)閉Firebug的編輯、調(diào)試和監(jiān)測功能,則需要單擊功能區(qū)最左邊的臭蟲圖標(biāo),打開主菜單,選擇“Disable Firebug”或“Disable Firebug for xxxxx”。
3、Firebug主菜單
單擊功能區(qū)最左邊的臭蟲圖標(biāo)可打開主菜單(圖3-1),其主要功能描述請看表1。
圖3-1
菜單選項 | 說明 |
Disable Firebug | 關(guān)閉/開啟Firebug對所有網(wǎng)頁的編輯、調(diào)試和檢測功能 |
Disable Firebug for xxxxx | 關(guān)閉/開啟Firebug對xxxxx網(wǎng)站的編輯、調(diào)試和檢測功能 |
Allowed Sites | 設(shè)置允許編輯、調(diào)試和檢測的網(wǎng)站 |
Text Size:Increase text size | 增大信息區(qū)域顯示文本的字號 |
Text Size:Decrease text size | 減少信息區(qū)域顯示文本的字號 |
Text Size:Normal text size | 信息區(qū)域以正常字體顯示 |
Options:Always Open in New Window | 設(shè)置Firebug控制窗口永遠(yuǎn)在新窗口打開 |
Show Preview tooltips | 設(shè)置是否顯示預(yù)覽提示。 |
Shade Box Model | 當(dāng)前查看狀態(tài)為HTML,鼠標(biāo)在HTML element標(biāo)簽上移動時,頁面會相應(yīng)在當(dāng)前標(biāo)簽顯示位置顯示一個邊框表示該標(biāo)簽范圍。這個選項的作用是設(shè)置是否用不同顏色背景表示標(biāo)簽范圍。 |
Firebug Website.. | 打開Firebug主頁。 |
Documentation.. | 打開Firebug文檔頁。 |
Discussion Group | 打開Firebug討論組。 |
Contribute | 打開捐助Firebug 頁面。 |
表1 |
4、控制臺(Console)
單擊功能區(qū)第二欄的“Console”標(biāo)簽可切換到控制臺(圖4-1)。控制臺的作用是顯示各種錯誤信息(可在Options里定義),顯示腳本代碼中內(nèi)嵌的控制臺調(diào)試信息,通過命令行對腳本進(jìn)行調(diào)試,通過單擊Profile對腳本進(jìn)行性能測試??刂婆_分兩個區(qū)域,一個是信息區(qū),一個是命令行,通過Options菜單的“Larger Command Line”可改變命令行位置。
圖4-1
Options菜單的選項請看表2。
菜單選項 | 說明 |
Show JavaScript Errors | 顯示腳本錯誤。 |
Show JavaScript Warnings | 顯示腳本警告。 |
Show CSS Errors | 顯示CSS錯誤。 |
Show XML Errors | 顯示XML錯誤。 |
Show XMLHttpRequests | 顯示XMLHttpRequests。 |
Larger Command Line | 將命令行顯示從控制窗口底部移動右邊,擴(kuò)大輸入?yún)^(qū)域。 |
表2 |
單擊“Clear”按鈕可清除控制臺的控制信息。
5、頁面源代碼查看功能
單擊功能區(qū)第二欄的“HTML”標(biāo)簽可切換到源代碼查看功能(圖5-1)。雖然Firefox也提供了查看頁面源代碼的功能,但它顯示的只是頁面文件本身的源代碼,通過腳本輸出的HTML源碼是看不到。而Firebug則是所見即所得,是最終的源代碼。
圖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選中部分)。
圖5-2
從圖5-1中我們可以看到,信息區(qū)被分成了兩個部分,左邊是顯示源代碼,右邊是一個功能區(qū),可以從這里查看到HTML Element中的CSS定義、布局情況和DOM結(jié)構(gòu)。
從圖5-2中我們可以看到,源代碼按DOM結(jié)構(gòu)分層次顯示的,通過層次折疊功能,我們就可以很方便分析代碼。在功能區(qū)的第一行還根據(jù)你的選擇,清晰的按子、父、根列出了當(dāng)前源代碼的層次(圖5-2紅色部分),單擊各部分,則會即刻轉(zhuǎn)到該部分的源代碼。
圖5-3
在源代碼上移動鼠標(biāo),頁面就會出現(xiàn)一個半透明的方塊,指示當(dāng)前鼠標(biāo)所指源代碼的顯示區(qū)域,當(dāng)選擇。在圖5-4中,鼠標(biāo)正指向“div1”,而在頁面中“div1”的顯示區(qū)域上被一個半透明的方塊遮蓋了。
圖5-4
如果你把“Inspect”按鈕按下,功能正好相反,在頁面中移動鼠標(biāo),則當(dāng)前顯示區(qū)域的源代碼會被加亮顯示出來。在圖5-5中,我們可以看到鼠標(biāo)指針正指向“方塊二”,而在源代碼中可以看到,“方塊二”的源代碼“<divid="div2">方塊二</div>”已被加亮顯示(紅色部分)。如果你單擊某個顯示區(qū)域,則該區(qū)域的源代碼會被選中。
圖5-5
是不是很方便?方便是方便,但是我的源代碼很多,而且有些區(qū)域在頁面中不方便鼠標(biāo)指定,怎么辦?沒關(guān)系,我們還有一個厲害武器,搜索功能。譬如我們知道某個HTMLElement的ID是“div2”,但在層層疊疊的源代碼中不好找,在頁面中鼠標(biāo)也很難找到,那我們就在功能區(qū)的搜索框中輸入“div2”,再看看源代碼區(qū)域,“div2”被加亮顯示出來了(圖5-6紅色部分)。在這個簡單的例子可能看不出很好的效果,大家可以嘗試一下把“div1”先折疊起來,然后在搜索框輸入“div3”,你可以看到“div1”會自動展開,并將“div3”加亮顯示,如果還覺得不夠理想,可以找一個源代碼比較多的例子測試一下。
圖5-6
除了通過按下“Inspect”按鈕,單擊顯示區(qū)域選擇源代碼,我們還可以通過單擊源代碼中的HTML標(biāo)記(開始或結(jié)束標(biāo)記都可以)來選擇。我們嘗試一下把鼠標(biāo)移動到HTML標(biāo)記,會發(fā)現(xiàn)鼠標(biāo)指針變成了手的形狀,這說明我們可以通過單擊選擇該源代碼。選擇源代碼后,我們就可以通過右邊的功能區(qū)查看、編輯和調(diào)試它的CSS定義和盒子模型(CSS盒子模型請參閱相關(guān)說明,這里就不再贅述了),還有一個很好的功能就是當(dāng)外部編輯器修改了源代碼(沒有刪除該源代碼,只是修改),我們在瀏覽器重新加載頁面后,選擇的源代碼不會改變,我們可以很方便的觀察源代碼的變化與效果。
有沒有經(jīng)常為調(diào)試某個頁面效果在源代碼編輯器和瀏覽器之間切換,一次又一次的刷新而感到懊惱?有了Firebug你就不用再懊惱了。你可以直接在源代碼中進(jìn)行編輯,然后查看效果。如果只是修改已經(jīng)存在的屬性,例如要修改“div2”的內(nèi)部文本,則直接將鼠標(biāo)移動到文本上面,等鼠標(biāo)指針換成“I”,單擊即可進(jìn)行編輯了。其它已存在的屬性和屬性值也可以這樣直接進(jìn)行編輯。如果要為某Element添加屬性,請將鼠標(biāo)移動到該Element上,等光標(biāo)變?yōu)椤癐”的時候,單擊鼠標(biāo)右鍵,從菜單中選擇“New Attribute..”,在顯示的編輯框中輸入你要添加的屬性名稱就可以了。
圖5-7
圖5-8
我們嘗試一下為“div2”增加一個“onclick”屬性,單擊的結(jié)果是將“div2”的顯示文本修改為“單擊”。把光標(biāo)移動到“div2”上,然后單擊鼠標(biāo)右鍵,選擇“NewAttribute..”(圖5-7),在編輯框中輸入“onclick”,最后按一下回車鍵(圖5-8),出現(xiàn)屬性值輸入框后,輸入“this.innerHTML=’單擊’”,回車后我們可以繼續(xù)添加下一個屬性,這次測試不需要,所以按ESC結(jié)束我們的輸入。我們來檢驗一下修改結(jié)果,單擊頁面“div2”的區(qū)域(圖5-9),“div2”的顯示文本已修改為“單擊”了,而源代碼也改變了。有沒有發(fā)現(xiàn),“div2”被加亮顯示了?這又是Firebug的一個功能。只要我們通過頁面中的操作修改了Element的屬性,F(xiàn)irebug就會在源代碼中通過加亮的方式指示當(dāng)前操作修改那些屬性值。譬如我們單擊某個鏈接修改了一個iframe里的src,那么這個src的屬性值就會被加亮顯示。又譬如我們單擊某個鏈接修改了一個image里的圖像,那么它的src屬性值也會被加亮顯示。我們可以通過Options菜單里的“HighlightChanges”設(shè)置是否加亮顯示改變。而“Expand Changes”則是設(shè)置被改變的源代碼折疊起來看不見時展開讓它可見。而“ScrollChanges into view”則是源代碼很多,被改變的源代碼不在可視區(qū)域時,將被改變的源代碼滾動到可視區(qū)域。
圖5-9
有時候我們不單是要增加一兩個屬性,而是要做更多的修改,這怎么辦呢?很簡單,選擇你要更改Element,然后單擊功能區(qū)第一行的“Edit”按鈕或者直接將鼠標(biāo)移動到要修改的Element上,單擊鼠標(biāo)右鍵,選擇“EditHTML..”,這時候,源代碼區(qū)域?qū)⑶袚Q到編輯狀態(tài),你可以隨意的修改你選擇的源代碼了。我們嘗試修改一下“div2”,將被修改顯示文本修改回“方塊二”,我們選擇“div2”,然后單擊“Edit”按鈕(圖5-10),將顯示文本修改回“方塊二”,然后再次單擊“Edit”按鈕退出編輯狀態(tài),如果要放棄修改,可以按ESC鍵退出。因為是所見即所得的,所以我們在修改的時候,頁面會同時刷新顯示。
圖5-10
在“Style”標(biāo)簽里我們可以選擇“Options”菜單里的“Show Computed Style”查看瀏覽器默認(rèn)的風(fēng)格定義。
圖5-11
圖5-12
圖5-13
圖5-14
圖5-15
如果不想在頁面中顯示標(biāo)尺和4條實線,可以不選擇“Options”菜單里的“Show Rules and Guides”。
圖5-16
圖5-17
圖5-18
圖5-19
在源代碼顯示區(qū)域我們還可以通過鼠標(biāo)右鍵復(fù)制源代碼和顯示內(nèi)容,這里就不一一說明了。DOM的說明請看查看DOM結(jié)構(gòu)一節(jié),兩者是一樣的。在源代碼區(qū)域中如果覺得源代碼顯示太密,可以將“Options”菜單里的“Show WhiteSpace”選項打開,每個源代碼塊之間會用空白行隔離。如果要查看源代碼的注釋內(nèi)容,請將“Options”菜單里的“ShowComments”選項打開。
這里要提醒大家一下,在HTML里調(diào)試出正確的源代碼和CSS后,別忘記將源代碼和CSS的修改結(jié)果復(fù)制到你的源代碼文件中,不然你的調(diào)試結(jié)果在頁面刷新后會付之東流。切記!切記!
6、查看CSS定義
將功能區(qū)第二行的標(biāo)簽切換到“CSS”,在這里我們可以查看頁面中所有的CSS定義,包括鏈接的CSS文件。通過功能區(qū)的文件選擇按鈕可以選擇不同的含有CSS的文件(圖6-1紅色圈住部分)。
圖6-1
CSS的定義的編輯這里就不再說明了,這個可以參考HTML的“Style”操作。
“Edit”按鈕功能和HTML的“Edit”功能類似。
7、腳本調(diào)試
將功能區(qū)第二行的標(biāo)簽切換到“Script”,在這里我們可以對頁面中所有的腳本進(jìn)行調(diào)試,包括鏈接的腳本。和CSS一樣,可以通過文件選擇按鈕選擇不同的腳本文件。
如果要在腳本中設(shè)置一個斷點,可以單擊行號旁邊的空白區(qū)域,這時會出現(xiàn)一個紅色的點表示在這里設(shè)置了斷點(圖7-1),當(dāng)腳本運(yùn)行到此會停止運(yùn)行,等待你的操作。在右邊的小窗口將標(biāo)簽切換到“Breakpoints”可以查看我們設(shè)置的所有斷點(圖7-2),單擊左上角的checkbox可以讓斷點不起作用,如果要刪除斷點可以單擊右上角的刪除圖標(biāo)。通過“Options”菜單的“Disable AllBreakpoints”可暫時禁止所有斷點,而“Remove AllBreakpoints”可刪除所有斷點。在斷點標(biāo)記的紅點上單擊右鍵還可以設(shè)置斷點條件,在符合條件的時候才會停止腳本的執(zhí)行。
圖7-1
圖7-2
下面我們來嘗試一下斷點的功能。首先在測試頁腳本里增加一個test的函數(shù),函數(shù)的主要操作是運(yùn)行一個1000次的循環(huán),將循環(huán)的參數(shù)值顯示在“div2”里:
function test(){
for(var i=0;i<1000;i++){
document.getElementById(‘div2‘).innerHTML=i;
}
}
在“div2”里增加一個“onclick”屬性,單擊后執(zhí)行test:
<div id="div2" onclick=‘test()‘>方塊二</div>
刷新頁面,然后在“for(var i=0;i<1000;i++){”這行上設(shè)置一個斷點,并設(shè)置條件為“i=100”(圖7-3),然后單擊“div2”開始執(zhí)行函數(shù)test。
圖7-3
當(dāng)腳本停下來后,我們將鼠標(biāo)移動到變量“i”上,這時會出現(xiàn)一個小方框,里面有一個數(shù)值,這就是變量“i“的當(dāng)前值(圖7-4)。在腳本調(diào)試的時候,你可以通過這個方法很方便的了解到當(dāng)前變量的值。你還可以通過右邊窗口的“Watch”標(biāo)簽查看到“i”的值(圖7-5)。
圖7-4
圖7-5
在“Watch”標(biāo)簽窗口我們可以通過“Options”菜單選擇查看用戶自定義屬性(Show User-definedProperties)、用戶自定義函數(shù)(Show User-defined Functions)、DOM屬性(Show DOMProperties)、DOM函數(shù)(Show DOM Functions)和DOM常數(shù)(Show DOMConstants)。我們還可以通過單擊“New watchexpression…”(圖7-6淡黃色背景部分)加入自己想跟蹤的內(nèi)容。例如我們想跟蹤一下“div2”的顯示內(nèi)容,就可以單擊“Newwatchexpression…”,加入“document.getElementById(‘div2‘).innerHTML”,輸入中可通過TAB鍵自動完成關(guān)鍵字的輸入(圖7-7)。如果不想跟蹤了,可單擊最右邊的刪除圖標(biāo)取消跟蹤。
圖7-6
圖7-7
腳本在斷點停止后,我們就可以利用搜索框旁的4個跟蹤按鈕進(jìn)行代碼跟蹤了(圖7-7)。第一按鈕是繼續(xù)運(yùn)行程序,不再執(zhí)行跟蹤,快捷鍵是F8。第二個按鈕是單步執(zhí)行方式,每次執(zhí)行一條語句,該方式在遇到函數(shù)調(diào)用時不進(jìn)入調(diào)用函數(shù)內(nèi)部進(jìn)行跟蹤,快捷鍵是F10。第三個按鈕也是單步執(zhí)行方式,每次執(zhí)行一條語句,但它遇到函數(shù)調(diào)用時會進(jìn)入調(diào)用函數(shù)內(nèi)部進(jìn)行跟蹤,快捷鍵是F11。當(dāng)你進(jìn)入調(diào)用函數(shù)內(nèi),想馬上跳出來時,可以單擊第四個按鈕,該按鈕沒有快捷鍵。
搜索框的作用和HTML源代碼查看是一樣的,不過有一個不同,就是輸入“#n”(n≥1),可以直接跳到腳本的第n行。
當(dāng)執(zhí)行腳本在“console”標(biāo)簽內(nèi)顯示一個錯誤,而錯誤的提示行左邊出現(xiàn)一個暗紅色的圓點時(圖7-8),我們可以單擊改紅點在該行設(shè)置一個斷點。
圖7-8
我們可以通過“Script”標(biāo)簽的“Options”菜單的“Break on All Errors”選項設(shè)置每當(dāng)腳本發(fā)生錯誤時就中斷腳本,進(jìn)入調(diào)試狀態(tài)。
有時候一個函數(shù)隨機(jī)出現(xiàn)錯誤,你不可能每次調(diào)用都去跟蹤一次,而產(chǎn)生錯誤的原因很可能是傳遞的參數(shù)錯誤,這時你可以通過跟蹤函數(shù)調(diào)用的功能去檢查每次調(diào)用函數(shù)時的參數(shù)情況。操作在函數(shù)腳本內(nèi)單擊鼠標(biāo)右鍵,在菜單中選擇“Log Calls toxxxxx”(xxxxx為函數(shù)名),然后可在“console”標(biāo)簽中可查看函數(shù)調(diào)用情況。
8、查看DOM結(jié)構(gòu)
將功能區(qū)第二行的標(biāo)簽切換到“DOM”可俺層次查看整個頁面的DOM結(jié)構(gòu)。通過“Options”菜單可自定義選擇查看用戶自定義屬性(ShowUser-defined Properties)、用戶自定義函數(shù)(Show User-definedFunctions)、DOM屬性(Show DOM Properties)、DOM函數(shù)(Show DOMFunctions)或DOM常數(shù)(Show DOM Constants)等內(nèi)容。
通過雙擊你可以修改DOM里面的屬性值。
9、查看網(wǎng)絡(luò)狀況
圖9-1
圖9-2
從圖中我們可以看到,頁面中每一個下載文件都用一個灰色條表示它相對其它文件是從什么時候開始下載的,下載時間是多少。在底部我們看到頁面發(fā)送了多少個請求,下載總量是多少,有多少是有緩存的,下載總共花費了多少時間等信息。
如果只想了解某一樣文件的下載情況,你可以單擊功能區(qū)第一欄的文件分類按鈕過濾文件(圖9-2紅色圈住區(qū)域1)。
將鼠標(biāo)在文件中移動,如果是圖片,我們可以看到圖片的縮略圖(圖9-2紅色圈住區(qū)域3)。
如果顯示為紅色的文件名,則表示該文件在服務(wù)器中不存在,不能下載,這樣你就要檢查一下文件的路徑是否正確或者是否上傳了該文件(圖9-2紅色圈住區(qū)域2)。
我們可以展開某個文件,查看它的HTTP頭信息和返回結(jié)果的信息。如果請求的是一個動態(tài)頁面或XMLHttpRequest,則還可以查看提交的變量。通過查看提交的變量和返回信息,我們可以很方便的調(diào)試程序是否正確提交了需要的變量和返回了正確的數(shù)據(jù)。例如從圖36中,我們可以看到向“topics-remote.php”發(fā)送了一個請求,提交的參數(shù)有“_dc”、“callback”、“l(fā)imit”和“start”四個,值分別為“1188637444000”、“stcCallback1001”、“25”與“0”,從這里我們可以很方便的知道我們腳本操作提交的參數(shù)是否正確。切換到“Response”頁可以看到返回的結(jié)果(圖9-3),在這里你可以對返回結(jié)果進(jìn)行檢查。如果你感覺在這里查看結(jié)果很亂,你可以單擊鼠標(biāo)右鍵,在彈出菜單中選擇“Copy Response body”復(fù)制結(jié)果到編輯器查看,你還可以選擇“Open in New Tab”打開一個新標(biāo)簽瀏覽。
圖9-3
通過右鍵菜單你可以復(fù)制文件地址(Copy Location)、HTTP請求頭信息(Copy Request Headers)和HTTP響應(yīng)頭信息(Copy Response Headers)。
如果不想使用該功能,可以選擇Options菜單的“Disable Network Monitoring”關(guān)閉該功能。
10、命令行調(diào)試
在“Console”標(biāo)簽了有一個命令行工具,我們可以在這里運(yùn)行一些腳本對頁面進(jìn)行調(diào)試。
我們在命令行中輸入“document.getElementById(‘div2‘).innerHTML”看看效果(圖10-1),別忘了用TAB鍵實現(xiàn)快速輸入關(guān)鍵字。在信息區(qū)顯示了當(dāng)前“div2”的顯示內(nèi)容。
圖10-1
要輸入“document.getElementById”是不是覺得很麻煩?這里有一個簡單的辦法,用“$”符號代替“document.getElementById”,我們再在命令行中輸入“$(‘div2‘).innerHTML”,然后看看結(jié)果,是一樣(圖10-2)。
圖10-2
當(dāng)你通過“Inspect”鎖定了一些HTML Element時,你可以通過“$1”來訪問最后一個Element,依次類推,我們可以通過“$n”(n>1)訪問依次倒序訪問鎖定的Element。
我們來實踐一下,刷新一下測試頁面,然后按下“Inspect”按鈕,鼠標(biāo)單擊“方塊二”,然后在按下“Inspect”按鈕,單擊“方塊一”。將firebug窗口切換回“Console”標(biāo)簽,然后輸入“$1”,回車后再輸入“$2”,查看一下結(jié)果(圖10-3),正是我們用鎖定過的Element。
圖10-3
在命令行還可以通過“$$(HTML 標(biāo)記)”返回一個Element數(shù)組。我們在測試頁輸入“$$(‘div’)”看看(圖10-4)。我們再輸入“$$(‘div’)[0]”看看(圖10-5)。是不是很便于我們對HTML進(jìn)行調(diào)試。
圖10-4
圖10-5
命令行的所有特殊函數(shù)請看表3:
命令 | 說明 |
$(id) | 通過id返回Element。 |
$$(selector) | 通過CSS選擇器返回Element數(shù)組。 |
$x(xpath) | 通過xpath表達(dá)式返回Element數(shù)組。 |
dir(object) | 列出對象的所有屬性,和在DOM標(biāo)簽頁查看該對象的是一樣的。 |
dirxml(node) | 列出節(jié)點的HTML或XML的源代碼樹,和在HTML標(biāo)簽頁查看改節(jié)點一樣。 |
cd(window) | 默認(rèn)情況下,命令行相關(guān)的是頂層window對象,使用該命令可切換到frame里的window獨享。 |
clear() | 清空信息顯示區(qū),和單擊按鈕Clear功能一樣。 |
inspect(object[, tabName]) | 監(jiān)視一個對象。tabName表示在那個標(biāo)簽頁對該對象進(jìn)行監(jiān)視,可選值為“html”、“css”、“script”和“dom”。 |
keys(object) | 返回由對象的屬性名組成的數(shù)組。 |
values(object) | 返回由對象的屬性值組成的數(shù)組。 |
debug(fn) | 在函數(shù)的第一行增加一個斷點。 |
undebug(fn) | 移除在函數(shù)第一行的斷點。 |
monitor(fn) | 跟蹤函數(shù)fn的調(diào)用。 |
unmonitor(fn) | 不跟蹤函數(shù)fn的調(diào)用。 |
monitorEvents(object[, types]) | 跟 蹤對象的事件。Types的可選值為“composition”、 “contextmenu”、 “drag”、 “focus”,、“form”、“key”、 “l(fā)oad”、“mouse”、“mutation”、“paint”、“scroll”、“text”、“ui”和“xul”。 |
unmonitorEvents(object[, types]) | 不 跟蹤對象的事件。Types的可選值為“composition”、 “contextmenu”、 “drag”、 “focus”,、“form”、“key”、 “l(fā)oad”、“mouse”、“mutation”、“paint”、“scroll”、“text”、“ui”和“xul”。 |
profile([title]) | 開始對腳本進(jìn)行性能測試,可選參數(shù)title將作為測試結(jié)果的標(biāo)題。 |
profileEnd() | 結(jié)束腳本性能測試。 |
表3 |
命令行有命令記憶功能,可通過上、下箭頭鍵選擇已經(jīng)輸入過的命令。
11、在腳本文件中加入調(diào)試命令
有沒有對腳本調(diào)試中經(jīng)常需要alert感到厭煩?有了Firebug,你就可以放下alert了,因為Firebug有功能比alert更強(qiáng)大的console.log。
先讓我們來認(rèn)識一下console.log,在測試文件腳本區(qū)域我們輸入一下代碼:
console.log(‘Hello‘);
刷新一下頁面,將firebug切換到“console”標(biāo)簽看看(圖11-1),在信息區(qū)顯示出了我們要輸出的信息“Hello”。當(dāng)然了,單憑這個就說console.log有點夸大,我們修改一下test函數(shù),把“document.getElementById(‘div2‘).innerHTML=i;”修改為:
console.log(‘當(dāng)前的參數(shù)是:%d‘,i);
圖11-1
刷新頁面后看看結(jié)果(圖11-2)。是不是挺不錯的?console.log可以象c語言的printf一樣實現(xiàn)格式化輸出。我們再在腳本區(qū)加入一個語句:
console.log(2,4,window,test,document);
圖11-2
刷新頁面后看看結(jié)果(圖11-3)。console.log可以連續(xù)輸出多個對象,而且如果對象是DOM、函數(shù),還可以直接點擊去到該對象。
圖11-3
如果你覺得console.log輸出的文本太單調(diào),不能表示出不同的信息,那么你可以通過console.debug、console.info、console.warn和console.error來代替console.log,這些函數(shù)分別會用不同的背景顏色和文字顏色來顯示信息。
我們來看看測試一下這些函數(shù)的輸出,在腳本中加入:
console.debug(‘This is console.debug!‘);
console.info(‘This is console.info!‘);
console.warn(‘This is console.warn!‘);
console.error(‘This is console.error!‘);
刷新頁面看看結(jié)果(圖11-4)。
圖11-4
有時候,為了更清楚方便的查看輸出信息,我們可能需要將一些調(diào)試信息進(jìn)行分組輸出,那么可以使用console.group來對信息進(jìn)行分組,在組信息輸出完成后用console.groupEnd結(jié)束分組。我們測試一下把剛才的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();
刷新頁面看看結(jié)果(圖11-5)。在console.group中,我們還可以加入一個組標(biāo)題“開始分組:”。如果需要,我們還可以通過嵌套的方式,在組內(nèi)再分組。
圖11-5
有時候,我們需要寫一個for循環(huán)列出一個對象的所有屬性或者某個HTMLElement下的所有節(jié)點,有了firebug后,我們不需要再寫這個for循環(huán)了,我們只需要使用console.dir(object)或console.dirxml(element)就可以了。
在測試頁中加入代碼測試一下:
console.dir(document.getElementById(‘div1‘));
console.dirxml(document.getElementById(‘div1‘));
結(jié)果請看圖11-6和圖11-7。
圖11-6
圖11-7
是否想知道代碼的運(yùn)行速度?很簡單,使用console.time和console.timeEnd就可以。
修改一下test函數(shù)的代碼,測試一下運(yùn)行1000次循環(huán)需要多少時間:
function test(){
console.time(‘test‘);
for(var i=0;i<1000;i++){
document.getElementById(‘div2‘).innerHTML=i;
//console.log(‘當(dāng)前的參數(shù)是:%d‘,i);
}
console.timeEnd(‘test‘);
}
刷新頁面,單擊“方塊二”,看看結(jié)果(圖11-8)。在這里要注意的是console.time和console.timeEnd里的參數(shù)要一致才會有正確的輸出,而該參數(shù)就是信息的標(biāo)題。
圖11-8
是否想知道某個函數(shù)是從哪里調(diào)用的?console..trace可幫助我們進(jìn)行追蹤。在test函數(shù)的結(jié)尾加入:
console.trace();
刷新頁面,單擊“方塊二”,看看結(jié)果(圖11-9)。結(jié)果顯示是在坐標(biāo)(97,187)的鼠標(biāo)單擊事件執(zhí)行了test函數(shù),而調(diào)用的腳本是在simple.html文件里的第1行。因為是在HTML里面的事件調(diào)用了test函數(shù),所以顯示的行號是第1行。如果是腳本,則會顯示調(diào)用腳本的行號,通過單擊可以直接去到調(diào)用行。
圖11-9
如果想在腳本某個位置設(shè)置斷點,可以在腳本中輸入“debugger”作為一行。當(dāng)腳本執(zhí)行到這一行時會停止執(zhí)行等待用戶操作,這時候可以通過切換到“Script”標(biāo)簽對腳本進(jìn)行調(diào)試。
Firebug還有其它的一些調(diào)試函數(shù),這里就不一一做介紹,有興趣可以自己測試。表4是所有函數(shù)的列表:
函數(shù) | 說明 |
console.log(object[, object, ...]) | 向控制臺輸出一個信息??梢暂斎攵鄠€參數(shù),輸出將已空格分隔各參數(shù)輸出。 第一參數(shù)可以包含格式化文本,例如: console.log(‘這里有%d個%s’,count,apple); 字符串格式: %s :字符串。 %d, %i:數(shù)字。 %f: 浮點數(shù)。 %o -超鏈接對象。 |
console.debug(object[, object, ...]) | 向控制臺輸出一個信息,信息包含一個超鏈接鏈接到輸出位置。 |
console.info(object[, object, ...]) | 向控制臺輸出一個帶信息圖標(biāo)和背景顏色的信息,信息包含一個超鏈接鏈接到輸出位置。 |
console.warn(object[, object, ...]) | 向控制臺輸出一個帶警告圖標(biāo)和背景顏色的信息,信息包含一個超鏈接鏈接到輸出位置。 |
console.error(object[, object, ...]) | 向控制臺輸出一個帶錯誤圖標(biāo)和背景顏色的信息,信息包含一個超鏈接鏈接到輸出位置。 |
console.assert(expression[, object, ...]) | 測試一個表示是否為true,如果為false,提交一個例外信息到控制臺。 |
console.dir(object) | 列出對象的所有屬性。 |
console.dirxml(node) | 列出HTML或XML Element的XML源樹。 |
console.trace() | 輸出堆棧的調(diào)用入口。 |
console.group(object[, object, ...]) | 將信息分組再輸出到控制臺。通過console.groupEnd()結(jié)束分組。 |
console.groupEnd() | 結(jié)束分組輸出。 |
console.time(name) | 創(chuàng)建一個名稱為name的計時器,計算代碼的執(zhí)行時間,調(diào)用console.timeEnd(name)停止計時器并輸出執(zhí)行時間。 |
console.timeEnd(name) | 停止名稱為name的計時器并輸出執(zhí)行時間。 |
console.profile([title]) | 開始對腳本進(jìn)行性能測試,title為測試標(biāo)題。 |
console.profileEnd() | 結(jié)束性能測試。 |
console.count([title]) | 計算代碼的執(zhí)行次數(shù)。titile作為輸出標(biāo)題。 |
表4 |
12、在IE中使用Firebug
Firebug是Firefox的一個擴(kuò)展,但是我習(xí)慣在IE中調(diào)試我的頁面怎么辦?如果在頁面腳本中加入console.log()將調(diào)試信息寫到Friebug,在IE中肯定是提示錯誤的,怎么辦?不用擔(dān)心,F(xiàn)rirebug提供了FrirbugLite腳本,可以插入頁面中模仿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()腳本出現(xiàn)錯誤信息,那么在頁面中加入一下語句:
<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標(biāo)簽中加入“debug=’true’”,例如:
<html debug="true">
在Friebug Lite中也有命令行,但是功能沒那么強(qiáng)。
13、快捷鍵和鼠標(biāo)操作
全局操作 | |
打開Firebug窗口 | F12 |
關(guān)閉Firebug窗口 | F12 |
在新窗口打開Firebug | Ctrl+F12 |
往前切換標(biāo)簽 | Ctrl+` |
將光標(biāo)移到命令行 | Ctrl+Shift+L |
將光標(biāo)移到搜索框 | Ctrl+Shift+K |
進(jìn)入Inspect模式 | Ctrl+Shift+C |
進(jìn)行JavaScript性能測試 | Ctrl+Shift+P |
重新執(zhí)行最后一條命令行命令 | Ctrl+Shift+E |
HTML標(biāo)簽 | |
編輯屬性 | 單擊屬性名或值 |
編輯文本節(jié)點 | 單擊文本 |
編輯Element | 雙擊Element標(biāo)記 |
移到路徑里的下一個節(jié)點 | Ctrl+. |
移到路徑里的上一個節(jié)點 | Ctrl+, |
HTML編輯 | |
完成編輯 | Return |
取消編輯 | Esc |
移到下一個區(qū)域 | Tab |
移到上一個區(qū)域 | Shift+Tab |
HTML Inspect 模式 | |
取消Inspect | Esc |
Inspect 父節(jié)點 | Ctrl+Up |
Inspect 子節(jié)點 | Ctrl+Down |
Script標(biāo)簽 | |
繼續(xù)運(yùn)行 | F5 |
Ctrl+/ | |
單步執(zhí)行(Step Over) | F10 |
Ctrl+‘ | |
單步執(zhí)行(Step Into) | F11 |
Ctrl+; | |
退出函數(shù)(Step Out) | Shift+F11 |
Ctrl+Shift+; | |
設(shè)置斷點 | 單擊行號 |
禁止斷點 | 在行號上Shift+Click |
編輯斷點條件 | 在行號上Right-Click |
運(yùn)行到當(dāng)前行 | 在行號上Middle-Click |
在行號上Ctrl+Click | |
移到堆棧中的下一個函數(shù) | Ctrl+. |
移到堆棧中的上一個函數(shù) | Ctrl+, |
將焦點切換到Scripts菜單 | Ctrl+Space |
將焦點切換到Watch編輯 | Ctrl+Shift+N |
DOM 標(biāo)簽 | |
編輯屬性 | 雙擊在空白 |
移到路徑中下一個對象 | Ctrl+. |
移到路徑中上一個對象 | Ctrl+, |
DOM 和Watch編輯 | |
結(jié)束編輯 | Return |
取消編輯 | Esc |
自動完成下一個屬性 | Tab |
自動完成上一個屬性 | Shift+Tab |
CSS標(biāo)簽 | |
編輯屬性 | 單擊屬性 |
插入新屬性 | 雙擊空白處 |
移動焦點到Style Sheets菜單 | Ctrl+Space |
CSS編輯 | |
完成編輯 | Return |
取消編輯 | Esc |
移到下一個區(qū)域 | Tab |
移到上一個區(qū)域 | Shift+Tab |
按步長1增加數(shù)值 | Up |
按步長1減少數(shù)值 | Down |
按步長10增加數(shù)值 | Page Up |
按步長10減少數(shù)值 | Page Down |
自動完成下一個關(guān)鍵字 | Up |
自動完成上一個關(guān)鍵字 | Down |
Layout標(biāo)簽 | |
編輯值 | 單擊值 |
Layout編輯 | |
完成編輯 | Return |
取消編輯 | Esc |
移到下一個區(qū)域 | Tab |
移到上一個區(qū)域 | Shift+Tab |
按步長1增加數(shù)值 | Up |
按步長1減少數(shù)值 | Down |
按步長10增加數(shù)值 | Page Up |
按步長10減少數(shù)值 | Page Down |
自動完成下一個關(guān)鍵字 | Up |
自動完成上一個關(guān)鍵字 | Down |
命令行 (小) | |
自動完成上一個屬性 | Tab |
自動完成下一個屬性 | Shift+Tab |
執(zhí)行 | Return |
Inspect結(jié)果 | Shift+Return |
打開結(jié)果鼠標(biāo)右鍵菜單 | Ctrl+Return |
命令行 (大) | |
執(zhí)行 | Ctrl+Return |
14、總結(jié)
真是意想不到,F(xiàn)irebug居然有那么多好功能居然是我不知道。通過寫本篇文章,才認(rèn)真的了解和學(xué)習(xí)了一次Firebug,越學(xué)越感覺到它的威力。不過我學(xué)的也只是皮毛,還有更多的功能和技巧需要在平時的使用中慢慢積累,因此這篇文章只是一個簡單的介紹,還有很多東西是沒有涉及到的,而且因為我本身水平與能力有限,所以文中會有很多錯誤與遺漏,希望大家能多多諒解與指正!多謝!
例子最終源代碼:
<!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āng)前的參數(shù)是:%d‘,i);
}
console.timeEnd(‘test‘);
console.trace();
}
</script>
</body>
</html>