目錄
目前,各大瀏覽器都自帶開發工具。以Chrome瀏覽器爲例,打開它的“開發者工具”(Developer Tools)的方法有三種。
-
按F12或者Control+Shift+i。
-
在菜單中選擇“工具”/“開發者工具”。
-
在一個頁面元素上,打開右鍵菜單,選擇其中的“Inspect Element”。
打開以後,可以看到在頂端有八個面板卡可供選擇,分別是:
-
Elements:用來調試網頁的HTML源碼和CSS代碼。
-
Resources:查看網頁加載的各種資源文件(比如代碼文件、字體文件、css文件等),以及在硬盤上創建的各種內容(比如本地緩存、Cookie、Local Storage等)。
-
Network:查看網頁的HTTP通信情況。
-
Sources:調試JavaScript代碼。
-
Timeline:查看各種網頁行爲隨時間變化的情況。
-
Profiles:查看網頁的性能情況,比如CPU和內存消耗。
-
Audits:提供網頁優化的建議。
-
Console:用來運行JavaScript命令。
這八個面板都有各自的用途,以下詳細介紹Console面板,也就是控制檯。
console對象代表瀏覽器的JavaScript控制檯。雖然它還不是標準,但是各大瀏覽器都原生支持,已經成爲事實上的標準。
console對象主要有兩個作用:
-
顯示網頁代碼運行時的錯誤信息。
-
提供了一個命令行接口,用來與網頁代碼互動。
console對象的接口有很多方法,可供開發者調用。
console.log方法
log方法用於在console窗口顯示信息。
如果參數是普通字符串,log方法將字符串內容顯示在console窗口。
console.log("Hello World")
// Hello World
console.log("a","b","c")
// a b c
如果參數是格式字符串(使用了格式佔位符),log方法將佔位符替換以後的內容,顯示在console窗口。
console.log(" %s + %s = %s", 1, 1, 2)
// 1 + 1 = 2
上面代碼的%s表示字符串的佔位符,其他佔位符還有
- %d, %i 整數
- %f 浮點數
- %o 對象的鏈接
- %c CSS格式字符串
log方法的兩種參數格式,可以結合在一起使用。
console.log(" %s + %s ", 1, 1, "= 2")
// 1 + 1 = 2
其他輸出方法:debug,info,warn,error方法
除了log,console對象還有四個輸出信息的方法:
-
debug:等同於log。
-
info:等同於log。
-
warn:輸出信息時,在最前面加一個黃色三角,表示警告。
-
error:輸出信息時,在最前面加一個紅色的叉,表示出錯。
這四個方法的用法與log完全一樣。
console.error("Error: %s (%i)", "Server is not responding",500)
// Error: Server is not responding (500)
console.warn('Warning! Too few nodes (%d)', document.childNodes.length)
// Warning! Too few nodes (1)
console.table方法
對於某些複合類型的數據,console.table方法可以將其轉爲表格顯示。
var languages = [
{ name: "JavaScript", fileExtension: ".js" },
{ name: "TypeScript", fileExtension: ".ts" },
{ name: "CoffeeScript", fileExtension: ".coffee" }
];
console.table(languages);
上面代碼的language,轉爲表格顯示如下。
(index) | name | fileExtension |
0 | “JavaScript” | “.js” |
1 | “TypeScript” | “.ts” |
2 | “CoffeeScript” | “.coffee” |
複合型數據轉爲表格顯示的條件是,必須擁有主鍵。對於上面的數組來說,主鍵就是數字鍵。對於對象來說,主鍵就是它的最外層鍵。
var languages = {
csharp: { name: "C#", paradigm: "object-oriented" },
fsharp: { name: "F#", paradigm: "functional" }
};
console.table(languages);
上面代碼的language,轉爲表格顯示如下。
(index) | name | paradigm |
csharp | “C#” | “object-oriented” |
fsharp | “F#” | “functional” |
console.assert方法
assert方法用來驗證某個條件是否爲真。如果爲假,則顯示一條事先指定的錯誤信息。它的格式如下。
console.assert(條件判斷,輸出信息)
使用方法如下。
console.assert(true === false,"判斷條件不成立")
// Assertion failed: 判斷條件不成立
下面是另一個例子,判斷子節點的個數是否大於等於500。
console.assert(list.childNodes.length < 500, "節點個數大於等於500")
time和timeEnd方法
這兩個方法用於計時,可以算出一個操作所花費的準確時間。
console.time("Array initialize");
var array= new Array(1000000);
for (var i = array.length - 1; i >= 0; i--) {
array[i] = new Object();
};
console.timeEnd("Array initialize");
// Array initialize: 1914.481ms
time方法表示計時開始,timeEnd方法表示計時結束。它們的參數是計時器的名稱。調用timeEnd方法之後,console窗口會顯示“計時器名稱: 所耗費的時間”。
分組方法:group和groupend
這兩個方法用於將顯示的信息分組。它只在輸出大量信息時有用,分在一組的信息,可以用鼠標摺疊/展開。
其他方法
-
console.dir:輸出對象的信息,用於顯示一個對象的所有屬性。
-
console.clear:對console窗口進行清屏,光標回到第一行。
-
console.trace:當前執行的代碼在堆棧中的調用路徑。
在控制檯中,除了使用console對象,還可以使用一些控制檯自帶的命令行方法。
(1)$_
$_屬性返回上一個表達式的值。
2+2
// 4
$_
// 4
(2)0 - 4
控制檯保存了最近5個在Elements面板選中的DOM元素,0代表倒數第一個, 1代表倒數第二個,以此類推直到$4。
(3)$(selector)
$(selector)返回一個數組,包括特定的CSS選擇器匹配的所有DOM元素。該方法實際上是document.querySelectorAll方法的別名。
var images = $('img');
for (each in images) {
console.log(images[each].src);
}
上面代碼打印出網頁中所有img元素的src屬性。
(4)$x(path)
$x(path)方法返回一個數組,包含匹配特定XPath表達式的所有DOM元素。
$x("//p[a]")
上面代碼返回所有包含a元素的p元素。
(5)inspect(object)
inspect(object)方法打開相關面板,並選中相應的元素:DOM元素在Elements面板中顯示,JavaScript對象在Profiles中顯示。
(6)getEventListeners(object)
getEventListeners(object)方法返回一個對象,該對象的成員爲登記了回調函數的各種事件(比如click或keydown),每個事件對應一個數組,數組的成員爲該事件的回調函數。
(7)keys(object),values(object)
keys(object)方法返回一個數組,包含特定對象的所有鍵名。
values(object)方法返回一個數組,包含特定對象的所有鍵值。
var o = {'p1':'a', 'p2':'b'};
keys(o)
// ["p1", "p2"]
values(o)
// ["a", "b"]
(8)monitorEvents(object[, events]) ,unmonitorEvents(object[, events])
monitorEvents(object[, events])方法監聽特定對象上發生的特定事件。當這種情況發生時,會返回一個Event對象,包含該事件的相關信息。unmonitorEvents方法用於停止監聽。
monitorEvents(window, "resize");
monitorEvents(window, ["resize", "scroll"])
上面代碼分別表示單個事件和多個事件的監聽方法。
monitorEvents($0, "mouse");
unmonitorEvents($0, "mousemove");
上面代碼表示如何停止監聽。
monitorEvents允許監聽同一大類的事件。所有事件可以分成四個大類。
- mouse:”mousedown”, “mouseup”, “click”, “dblclick”, “mousemove”, “mouseover”, “mouseout”, “mousewheel”
- key:”keydown”, “keyup”, “keypress”, “textInput”
- touch:”touchstart”, “touchmove”, “touchend”, “touchcancel”
- control:”resize”, “scroll”, “zoom”, “focus”, “blur”, “select”, “change”, “submit”, “reset”
monitorEvents($("#msg"), "key");
上面代碼表示監聽所有key大類的事件。
(9)profile([name]),profileEnd()
profile方法用於啓動一個特定名稱的CPU性能測試,profileEnd方法用於結束該性能測試。
profile("My profile")
profileEnd("My profile")
(10)其他方法
命令行API還提供以下方法。
- clear()方法清除控制檯的歷史。
- copy(object)方法複製特定DOM元素到剪貼板。
- dir(object)方法顯示特定對象的所有屬性,是console.dir方法的別名。
- dirxml(object)方法顯示特定對象的XML形式,是console.dirxml方法的別名。
debugger語句必須與除錯工具配合使用,如果沒有除錯工具,debugger語句不會產生任何結果。
在chrome瀏覽器中,當代碼運行到debugger指定的行時,就會暫停運行,自動打開console界面。它的作用類似於設置斷點。
for(var i = 0;i<5;i++){
console.log(i);
if (i===2) debugger;
}
上面代碼打印出0,1,2以後,就會暫停,自動打開console窗口,等待進一步處理。
(本節暫存此處)
模擬手機視口(viewport)
chrome瀏覽器的開發者工具,提供一個選項,可以模擬手機屏幕的顯示效果。
打開“設置”的Overrides面板,選擇相應的User Agent和Device Metrics選項。
User Agent可以使得當前瀏覽器發出手機瀏覽器的Agent字符串,Device Metrics則使得當前瀏覽器的視口變爲手機的視口大小。這兩個選項可以獨立選擇,不一定同時選中。
模擬touch事件
我們可以在PC端模擬JavaScript的touch事件。
首先,打開chrome瀏覽器的開發者工具,選擇“設置”中的Overrides面板,勾選“Enable touch events”選項。
然後,鼠標就會觸發touchstart、touchmove和touchend事件。(此時,鼠標本身的事件依然有效。)
至於多點觸摸,必須要有支持這個功能的設備才能模擬,具體可以參考Multi-touch web development。
模擬經緯度
chrome瀏覽器的開發者工具,還可以模擬當前的經緯度數據。打開“設置”的Overrides面板,選中Override Geolocation選項,並填入相應經度和緯度數據。
遠程除錯
(1) Chrome for Android
Android設備上的Chrome瀏覽器支持USB除錯。PC端需要安裝Android SDK和Chrome瀏覽器,然後用usb線將手機和PC連起來,可參考官方文檔。
(2) Opera
Opera瀏覽器的除錯環境Dragonfly支持遠程除錯(教程)。
(3) Firefox for Android
參考官方文檔。
(4) Safari on iOS6
你可以使用Mac桌面電腦的Safari 6瀏覽器,進行遠程除錯(教程)。
(本節暫存此處)
Google Closure是Google提供的一個JavaScript源碼處理工具,主要用於壓縮和合並多個JavaScript腳本文件。
Google Closure使用Java語言開發,使用之前必須先安裝Java。然後,前往官方網站進行下載,這裏我們主要使用其中的編譯器(compiler)。
首先,查看使用幫助。
java -jar /path/to/closure/compiler.jar --help
直接在腳本命令後面跟上要合併的腳本,就能完成合並。
java -jar /path/to/closure/compiler.jar *.js
使用–js參數,可以確保按照參數的先後次序合併文件。
java -jar /path/to/closure/compiler.jar --js script1.js --js script2.js --js script3.js
但是,這樣的運行結果是將合併後的文件全部輸出到屏幕(標準輸出),因此需要使用–js_output_file參數,指定合併後的文件名。
java -jar /path/to/closure/compiler.jar --js script1.js --js script2.js --js script3.js --js_output_file scripts-compiled.js
(本節暫存此處)
第一種做法
最常見的測試性能的做法,就是同一操作重複n次,然後計算每次操作的平均時間。
var totalTime,
start = new Date,
iterations = 6;
while (iterations--) {
// Code snippet goes here
}
// totalTime → the number of milliseconds it took to execute
// the code snippet 6 times
totalTime = new Date - start;
上面代碼的問題在於,由於計算機的性能不斷提高,如果只重複6次,很可能得到0毫秒的結果,即不到1毫秒,Javascript引擎無法測量。
第二種做法
另一種思路是,測試單位時間內完成了多少次操作。
var hz,
period,
startTime = new Date,
runs = 0;
do {
// Code snippet goes here
runs++;
totalTime = new Date - startTime;
} while (totalTime < 1000);
// convert ms to seconds
totalTime /= 1000;
// period → how long per operation
period = totalTime / runs;
// hz → the number of operations per second
hz = 1 / period;
// can be shortened to
// hz = (runs * 1000) / totalTime;
這種做法的注意之處在於,測試結構受外界環境影響很大,爲了得到正確結構,必須重複多次。