1 介绍
Chrome 开发者工具(简称 DevTools)是一组网页制作和调试的工具,内嵌于 Google Chrome 浏览器中。DevTools 使开发者更加深入的了解浏览器内部以及他们编写的应用。通过使用 DevTools,可以更加高效的定位页面布局问题,设置 JavaScript 断点并且更好的理解代码优化。
2 打开方式
-
常规方式
- 在浏览器窗口的右上方选择 Chrome 菜单, 然后选择工具 > 开发者工具
- 再页面上任意位置, 右键 > 检查
-
快捷键方式
-
DevTools(默认上次打开的功能俎)
- mac: command + option + i
- windows: control + shift + i
-
控制台
- mac: command + option + j
- windows: control + shift + j
-
element(元素审查)
- mac: command + option + c / command + shift+C
- windows: control + shift + c
-
3 面板组成
- element
- console
- sources
- network
- application
performance(性能分析)memory(内存)security(安全)Lighthouse(页面分析)
3.1 element
3.1.1. HTML 面板(元素)
3.1.1.1 元素选择
- 点击检查元素 icon (面板左上角箭头,快捷键:command + shift + c),鼠标在页面中选中元素背景被高亮成蓝色
- 打开开发者工具,点击 dom 树的某个元素节点,选中节点的背景被高亮成蓝色。
- 页面鼠标移动到元素 > 右键 > 检查 > 打开开发者工具后自动将鼠标定位的元素选中,背景高亮成蓝色。
- 在 console 面板中执行 document 相关 dom 查询
3.1.1.2 交换位置
- drag 拖拽
- 快捷键上下移动
mac: command + [⬆] / command + [⬇]
win: control + [⬆] / control + [⬇]
3.1.1.3 删除
- 选中元素,按 delete
- 右键 -> Delete element
3.1.1.4 选中
-
add attribute: 增加属性
-
edit attribute: 修改属性(只有当指针处于属性上才会显示)
-
edit as html 当成 html 编辑,可以随意更改
-
duplicate element 拷贝一份当前 div 并放置下方
-
delete element 删除节点
-
copy
- cut、copy、paste
- copy outreHTML 复制 html 内容
- copy selector 复制 CSS Selector
- copy js path 直接复制成 js 代码,指向当前节点
- copy styles 支持 css 属性
- copy xpath 获取相对路径
- copy full xpath 获取绝对路径
-Hide element 隐藏节点
-
force state 点击状态
-
Break on
- subtree modifications 子树修改
- attribute modifications 属性修改
- node removal 删除节点
-
expand recursively 递归展开
-
Collapse children 折叠子项
-
Capture node screenshot 节点截图
-
Scroll into view 滑动到节点位置
-
Focus 聚焦
-
Store as global variable 存为全局变量
3.1.1.5 Tips!!!
-
显示、隐藏元素
场景:可以按下'h'来隐藏在元素面板中被你选中的元素,再次按下'h'使它出现。某些时候这是很有用的,例如你想截图,但是又不想里面包含一些敏感信息 -
快速控制节点的展开与折叠
左键(left):折叠子元素;
右键(right):展开子元素;
[⬆]/[⬇]:上下选择节点; -
命令菜单
-
command + shift + p 打开命令菜单
-
截屏快捷键
-
输入 screenshot
-
选择对应的方式
- Capture area screenshot: 截取选择区域
- Capture full size screenshot: 整页截屏
- Capture node screenshot:捕捉选中节点
- Capture screenshot: 捕捉页面可视区的内容
-
-
改变窗口位置
- 输入 dock
undock 独立窗口
- 输入 dock
-
-
console 中快速打印节点
- 4:最近选择过的 5 个 DOM 节点。1 返回上上次选的 DOM 节点。最多可保存 5 个,如果不满 5 个,则返回 undefined。
- Store as global variable:将元素存储为全局变量,保存之后节点的全局变量名为 temp1、temp2...以此类推。
-
$_ 返回上一条语句的返回结果
3.1.2. DOM 样式(CSS)、结构
3.1.2.1 styles
- 选中类 > 点击空白 > 输入样式(输入之后按 Enter 保存样式)
- color 颜色选择器(鼠标点击颜色方块会出现颜色选择器)
改变颜色格式:在颜色预览中用 Shift + Click,可以在 rgba,hsl 和 hexadecimal(十六进制)这三种格式中切换。 - auto-complete: 自动补全
3.1.2.2 computed 窗格
3.1.2.2.1 查看元素盒模型
- 查看 width、height、padding、border、margin...度量单位可以是 px、百分比、vm 等。
3.1.2.2.2 关于 computed 中的样式
- 显示顺序是按字母顺序显示
- 显示的是真正作用在元素上的样式:style 中的样式可能是全部的样式,包括一些不起作用的样式。可实时查看更新样式是否生效。
- 查看继承的 css 属性
- 勾选 computed 中的 show all 复选框,展示元素所有的属性样式。
- 通过 filter 可以过滤/查找某些属性/值(styles、computed...都有这个选项)
3.1.2.2.3 EventListeners
当前 dom 下的事件
3.1.2.2.4 Properties
查看元素具有的方法与属性,比查 API 手册要方便。
3.2 console
3.2.1 打开方式
- command + option + j / control + shift + i
- 处于其他面板时:command + shift + p > 搜索 console > 选择 Drawer Show Console
3.2.2 Console 对象(宿主环境提供)
- console.log()/console.info: 输出信息
console.log(123); // 123
// 支持的占位符有:(样式)%c 字符(%s)、整数(%d或%i)、浮点数(%f)和对象(%o
console.log("%c样式", "color: red; font-size: 20px");
// 多种样式
console.log("%cBlue! %cRed!", "color: blue;", "color: red;");
console.log("%d年%d月%d日", 2011, 3, 26); // 2011年3月26日
console.log("%o", { a: { b: { c: [1, 2, 3] } } });
console.log("%O", { a: { b: { c: [1, 2, 3] } } });
- console.dir():将一个对象以 JSON 表达式的格式打印
- console.warn(): 警告信息
- console.error(): 输出信息时,在最前面加一个红色的叉,表示出错,同时会显示错误发生的堆栈
- console.assert():接受两个参数,第一个参数是表达式,第二个参数是字符串。只有当第一个参数为 false,才会输出第二个参数,否则不会有任何结果
console.assert(true === false, 123); // Assertion failed: 123
console.assert(1 == true, 123);
- console.count(): 计数,输出它被调用了多少次
- console.countReset(): 重制
(function () {
for (let i = 0; i < 5; i++) {
console.count("count");
}
})();
// count: 1
// count: 2
// count: 3
// count: 4
// count: 5
for (let i = 0; i < 10; i++) {
if (i === 5) {
console.countReset();
} else {
console.count();
}
}
// default: 1
// default: 2
// default: 3
// default: 4
// default: 5
// default: 1
// default: 2
// default: 3
// default: 4
- console.group(): 用于将显示的信息分组,可以把信息进行折叠和展开。
console.group("第一层");
console.group("第二层");
console.log("error");
console.error("error");
console.warn("error");
console.groupEnd();
console.log("error");
console.error("error");
console.warn("error");
console.groupEnd();
- console.table(): 将复合类型的数据转为表格显示。
- console.time(): 用于计时
console.time("计时器1");
for (let i = 0; i < 100; i++) {
for (let j = 0; j < 100; j++) {}
}
console.timeEnd("计时器1");
console.time("计时器2");
for (let i = 0; i < 1000; i++) {
for (let j = 0; j < 1000; j++) {}
}
console.timeEnd("计时器2");
- console.trace() 追踪函数的调用过程
function d(a) {
console.trace();
return a;
}
function b(a) {
return c(a);
}
function c(a) {
return d(a);
}
let a = b("123");
- cosnsole.profile: 性能分析,就是分析程序各个部分的运行时间,找出瓶颈所在(菜单面板 > profile)
function All() {
alert(1);
for (let i = 0; i < 10; i++) {
funcA(10000);
}
funcB(10000);
}
function funcA(count) {
for (let i = 0; i < count; i++) {}
}
function funcB(count) {
for (var i = 0; i < count; i++) {}
}
console.profile("性能分析器");
All();
console.profileEnd();
- clear(): 清空控制台
3.2.3 Tips!!!
- console 代码换行:Chrome 控制台回车默认是执行,要想输入换行,应按 Shift + Enter
- copy():复制一个具体对象的字符串表达式到剪切板,如 copy($0)
- getEventListeners(document.documentElement)返回在 DOM 元素上注册的所有的事件
- preserve log 保留历史记录, 打开后 clear()
- monitorEvents(): 会输出指定监控目标的事件信息。该方法的第一个参数表示被监控的对象,第二个参数表示要监控的事件,如果不填则会默认返回该对象上所有事件的监控信息。你可以将数组传入第二个参数,来同时监控多个事件。
3.3 sources
3.3.1 组成
- 文件导航窗格:列出了页面请求的每个文件;
- 代码编辑窗格:在文件导航窗格选择文件后,代码编辑窗格会显示选中文件的内容;
- js 调试窗格:检查页面 js 的各种工具。
3.3.2 js 调试窗格
-
调试按钮从左到右:
- 暂停/继续脚本执行:如果一个函数里有大量代码,但是大部分代码与定位的问题无关,点击该按钮(或者光标放到下一个要执行的断点行然后右键选择 continue to here 可以直接到该行的 debugger)可用于跳过冗长的代码片段,执行到下一个断点处(与定位问题相关的代码处)。
- 单步调试(快捷键 f10):不遇到函数,执行下一步;遇到函数,不进入函数,直接执行下一步;
- 进入函数调试(快捷键 f11):不遇到函数,执行下一步;遇到函数,进入函数执行上下文;
- step 下一步(遇到函数会进入)
- 跳出当前函数;
- 禁止所有的断点,停止任何调试;
- 程序运行遇到异常时是否中断调试: 当启动此功能并且开发者工具是打开着的时候,任何一个脚本的错误都会导致该脚本执行自动暂停。然后我们可以分析变量来看一下什么出错了。因此如果我们的脚本因为错误挂掉的时候,我们可以打开调试器,启用这个选项然后重载页面,查看一下哪里导致它挂掉了和当时的上下文是什么。
-
scope: 作用域链(代码中有闭包时 scope 窗格关注会多些,比如调试闭包中的 this 指向)。
-
breakpoints: 设置的断点全部显示在这里,可以快速定位到文件中断点的位置。
-
XHR/fetch breakpoints: 发请求的断点,比如可以在发 ajax 请求中打的断点。
-
DOM Breakpoints: js 改变 dom 节点属性、dom 节点子节点树改动、移除 dom 节点操作时打的断点全部显示在这个窗格。
-
global listeners: 全局监听器,在浏览器中 window 是全局对象,所以在 Global Listeners 面板中显示绑定在 window 对象上的事件监听。
-
event listener breakpoints:事件监听断点,比如鼠标的 click 事件,键盘 keydown 事件等。勾选事件前面的单选框即可监听该事件。
3.3.3 断点(在代码执行过程中暂停代码,同时检查所有相关的变量的值)
-
添加断点的方式
- 可以在代码里加 debugger 调试;
- 在代码编辑窗格直接打断点
-
DOM 相关的断点
- 子节点树改变、节点属性改变、节点移除
-
条件断点(Conditional breakpoints)
场景:有时设置的断点被执行太多次了:比如有一个对 200 个元素的循环,但我们只对第 110 次循环的结果感兴趣,或者只对一些满足其他的特殊条件的结果感兴趣,这样的情况下就可以设置一个条件断点。
操作:- 右击行号并且选择 Add conditional breakpoint(添加条件断点)的选项
- 或者右击一个已经设置的断点并且选择 Edit breakpoint(编辑断点)
- 然后输入一个执行结果为 true 或者 false 的表达式(它的值并不需要明确的为 true 或者 false,可以是表达式的结果为 true 或 false)。如果条件满足的话,断点就会暂停代码的执行
function test() {
for (let i = 0; i < 100; i++) {
console.log(i);
}
}
test();
3.3.4 workspaces
将项目文件夹直接拖到 workspaces 面板,DevTools 会将对文件的修改同步到系统文件中
3.3.5 snippets
在任何页面创建、运行、保存代码段、小脚本
document.getElementsByClassName("feedback")[0].click();
3.3.6 Tips!!!
-
command + p: 直接定位到某一行
-
快速查找文件&搜索特定字符串
-
多列内容选择:按住 Opt 键,当鼠标箭头变为“+”号后,点击鼠标;
-
匹配相同选项:选中需要匹配的元素,快捷键 Cmd + D
-
corverage:获取关于冗余代码的摘要-细节信息
- 打开: 右下角/ corverage 命令
- 打开 coverage 窗格,start 开始统计当前加载页面的代码,reload 按钮开始统计并重新加载页面
- coverage 窗格展示了在浏览器加载时每个加载的 css 和 js 文件中有多少使用和未使用的部分。(绿色是已使用的,红色是未使用的)
- 点击文件可以一行一行查看哪些部分被使用了哪些未被使用
3.4 network
3.4.1 工具栏
3.4.1.1 Preserve log(跨页面加载保存请求)
如页面跳转,勾选 Preserve log 复选框后 DevTool 会保存所有请求。
3.4.1.2 Disable cache(更改加载行为)
勾选 Disable cache 复选框可以停用浏览器缓存来模拟首次访问者,即可模拟新用户访问。
在其它面板中停用浏览器缓存:command menu 打开 Network conditions 抽屉,勾选/取消 Disable cache 复选框。
3.4.1.3 搜索/过滤网络日志:字符串搜索
按类型过滤请求:XHR、JS、CSS、Img、Media、Font、Doc、WS (WebSocket)、Manifest......
3.4.1.4 隐藏数据网址
数据网址是嵌入到其它文档中的小文件,在 Request 表格中看到的以 data:开头的所有请求都是数据网址,如图片的 base64 格式。
3.4.2 网络请求表格
- Name:资源的文件名或标识符
- Status:http 请求响应状态码
- Type:资源类型
- Initiator:启动源,发起请求的对象、进程,这些对象或进程包括 Parser、Redirect、Script、Other。(鼠标 hover 到该列可以看到调用堆栈的信息)
- Size:响应头和响应内容组合的大小
- Time:请求开始到从响应中接收到最终字节的总时间。
- Waterfall:瀑布流,各请求相关活动的直观分析图。
- content download:请求下载花费的时间
- stalled: 请求会因为高优先级请求到达、和目标服务器已经建立了 6 个 TCP 连接等原因而阻塞
3.4.3 查看请求的详情
在 Request 表格的 Name 列下,点击请求的地址
3.4.4 查看请求的发起者和依赖项
按住 Shift,然后鼠标指针悬停在 Requests 表格中的请求上。绿色请求表示发起者,红色表示依赖项。
3.5 Application
Application 面板主要记录网站加载的所有资源信息,包括存储数据(Local Storage、Session Storage、IndexedDB、Web SQL、Cookies)、缓存数据、字体、图片、脚本、样式表等。
3.5.1 Application
-
Mainfest: manifest.json 文件,其作用是用来告诉浏览器如何在用户的桌面上"安装"这个 app,及安装后该展示的信息。在 Application 面板中,主要是展示其信息,不具有操作性质。 例如:demo
-
Service Workers: 是浏览器在后台独立于网页运行的脚本,它们已包括如推送通知和后台同步等功能,支持离线应用,每 24 小时都会更新本地的离线脚本。
- 它是一种 JavaScript Worker,无法直接访问 DOM。 Service Worker 通过响应 postMessage 接口发送的消息来与其控制的页面通信,页面可在必要时对 DOM 执行操作。
- Service Worker 是一种可编程网络代理,让您能够控制页面所发送网络请求的处理方式。
- Service Worker 在不用时会被中止,并在下次有需要时重启
- Service Worker 可以访问 IndexedDB。
-
Clear storage: 清除 Service Worker、Storage、数据库和缓存
3.5.2 Storage
3.5.2.1 Local Storage / Session Storage
- 双击键或值可以修改相应的值。
- 双击空白单元格可以添加新条目。
- 点击对应的条目 ,然后按 Delete 按钮可以删除该该条目。
- 点击 refresh 按钮可以查看您的更改。
3.5.2.2 IndexedDB 一种在用户浏览器中持久存储数据的方法。
const IDBOpenDBRequest = indexedDB.open("testDB", 1);
// 创建一个新的数据库或者增加已存在的数据库的版本号, 触发onupgradeneeded
IDBOpenDBRequest.onupgradeneeded = (e) => {
const db = IDBOpenDBRequest.result;
// 对象仓库
const store = db.createObjectStore("User", {
keyPath: "name",
});
// 对象属性
store.createIndex("name", "name");
store.createIndex("age", "age");
store.createIndex("sex", "sex");
const bookStore = db.createObjectStore("Class", {
keyPath: "id",
autoIncrement: true,
});
bookStore.createIndex("className", "className");
bookStore.createIndex("classId", "classId");
bookStore.createIndex("status", "status");
};
IDBOpenDBRequest.onsuccess = (e) => {
const db = IDBOpenDBRequest.result;
// 创建事务
const transaction = db.transaction(["User", "Class"], "readwrite");
// 访问对象仓库
const objStore = transaction.objectStore("User");
const objClassStore = transaction.objectStore("Class");
// User 表加2条数据
objStore.put({
name: "xiaoming",
age: 18,
sex: 1,
});
objStore.put({
name: "xiaohong",
age: 18,
sex: 2,
});
// Book 表加一条数据
objClassStore.put({
className: "一年级",
classId: 1,
status: 1,
});
};
const transaction = IDBOpenDBRequest.result.transaction(["User"], "readwrite");
const objectStore = transaction.objectStore("User");
// 获取
const request = objectStore.get("xiaoming");
// 删除
objectStore.delete("xiaohong");
// 修改
request.onsuccess = (e) => {
const data = e.target.result;
data.age++;
objectStore.put(data);
};
3.5.2.3 Cookies
- name 键名
- value 值
- Domain 和 Path 标识定义了 Cookie 的作用域。Domain 标识指定了哪些主机可以接受 Cookie。Path 标识指定了主机下的哪些路径可以接受 Cookie
- Expires / Max-Age. Cookie 的过期时间或最长周期。对于会话 cookie,这一领域始终是 Session(会话)。
- Size Cookie 的大小,以字节为单位。
- HttpOnly 如果存在,则指示应仅通过 HTTP 使用 cookie,并且不允许 JavaScript 修改.
- SameSite Strict 允许服务器要求某个 cookie 在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击(CSRF)。Lax 则可以被发送
3.5.2.4 Web SQL 一组使用 SQL 操作客户端数据库的 APIs
openDatabase:这个方法使用现有的数据库或者新建的数据库创建一个数据库对象。
transaction:这个方法让我们能够控制一个事务,以及基于这种情况执行提交或者回滚。
executeSql:这个方法用于执行实际的 SQL 查询
const db = openDatabase("testdb", "1.0", "Test DB", 2 * 1024 * 1024);
db.transaction((tx) => {
tx.executeSql("CREATE TABLE IF NOT EXISTS LOGS (id unique, log)");
tx.executeSql('INSERT INTO LOGS (id, log) VALUES (1, "test1")');
tx.executeSql('INSERT INTO LOGS (id, log) VALUES (2, "test2")');
});
// 查
db.transaction((tx) => {
tx.executeSql(
"SELECT * FROM LOGS",
[],
function (tx, results) {
console.log(results);
var len = results.rows.length;
console.log(len);
console.table(results.rows);
},
null
);
});
// 删
db.transaction(function (tx) {
tx.executeSql("DELETE FROM LOGS WHERE id=1");
});
// 改
db.transaction(function (tx) {
tx.executeSql("UPDATE LOGS SET log='test3' WHERE id=2");
});
3.5.3 Cache
- Cache Storage
- Application Cache:应用缓存。可以使用 Application Cache 窗格去查看通过 Application Cache API 创建的资源(即离线资源缓存,如 manifest 缓存清单中的文件)。