likes
comments
collection
share

关于浏览器调试的30个奇淫技巧

作者站长头像
站长
· 阅读数 39

这篇文章为大家介绍一下浏览器的调试技巧,可帮助你充分利用浏览器的调试器。

console.log

这个是日常开发中最常用的了如果不知道这个就不是程序员了,这里不多描述了

console.count

计算代码执行的次数他会自动累加

// 例如我代码执行了三次
console.count()  // 1 2 3
console.count('执行:')  // 执行:1  执行:2  执行:3

console.table

例如,每当你的应用程序在调试器中暂停时,要将 localStorage 的数据转储出来,你可以创建一个 console.table(localStorage) 观察器:

关于浏览器调试的30个奇淫技巧

关于 console.table 的就暂时介绍到这里,下边有一篇详细介绍 console 其他用法的有兴趣的童靴可以去看看。

DOM 元素变化后执行表达式

要在 DOM 变化后执行表达式,需要设置一个 DOM 变化断点(在元素检查器中):

关于浏览器调试的30个奇淫技巧

然后添加你的表达式,例如记录 DOM 的快照:(window.doms = window.doms || []).push(document.documentElement.outerHTML)。现在,每当 DOM 子树发生修改时,调试器将暂停执行,并且新的 DOM 快照将位于 window.doms 数组的末尾。(无法创建不暂停执行的 DOM 变化断点。)

跟踪调用堆栈

假设你有一个显示加载动画的函数和一个隐藏加载动画的函数,但是在你的代码中,你调用了 show 方法却没有对应的 hide 调用。你如何找到未配对的 show 调用的来源?在 show 方法中使用条件断点中的 console.trace,运行你的代码,找到 show 方法的最后一个堆栈跟踪,并点击调用者来查看代码:

关于浏览器调试的30个奇淫技巧

改变程序行为

通过在具有副作用的表达式上使用,我们可以在浏览器中实时改变程序行为。

例如,你可以覆盖 getPerson 函数的参数 id。由于 id=1 会被评估为 true,这个条件断点会暂停调试器。为了防止这种情况发生,可以在表达式末尾添加 false:

关于浏览器调试的30个奇淫技巧

性能分析

你不应该在性能分析中混入诸如条件断点评估时间之类的内容,但如果你想快速而精确地测量某个操作运行所需的时间,你可以在条件断点中使用控制台计时 API。在你想要开始计时的地方设置一个带有条件 console.time('label') 的断点,在结束点设置一个带有条件 console.timeEnd('label') 的断点。每当你要测量的操作运行时,浏览器就会在控制台记录它花费了多长时间:

关于浏览器调试的30个奇淫技巧

根据参数个数进行断点

只有当当前函数被调用时带有 3 个参数时才暂停:arguments.callee.length === 3

当你有一个具有可选参数的重载函数时,这个技巧非常有用:

关于浏览器调试的30个奇淫技巧

当前函数调用参数数量错误时

只有当当前函数被调用时参数数量不匹配时才暂停:(arguments.callee.length) !== arguments.length在查找函数调用站点中的错误时很有用:

关于浏览器调试的30个奇淫技巧

跳过页面加载统计使用时间

直到页面加载后的 5 秒后才暂停:performance.now() > 5000

当你想设置一个断点,但只有在初始页面加载后才对暂停执行感兴趣时,这个技巧很有用。

跳过 N 秒

如果断点在接下来的 5 秒内触发,则不要暂停执行,但在之后的任何时候都要暂停:

window.baseline = window.baseline || Date.now(), (Date.now() - window.baseline) > 5000

随时可以从控制台重置计数器:window.baseline = Date.now()

使用 CSS

基于计算后的 CSS 值暂停执行,例如,仅当文档主体具有红色背景时才暂停执行:window.getComputedStyle(document.body).backgroundColor === "rgb(255,0,0)"

仅偶数次调用

仅在执行该行的每一次的偶数次调用时暂停:window.counter = (window.counter || 0) + 1, window.counter % 2 === 0

抽样断点

只在该行执行的随机样本上断点,例如,仅在执行该行的每十次中断点一次:Math.random() < 0.1

Never Pause Here

当你右键点击边栏并选择“Never Pause Here”时,Chrome 创建一个条件断点,该断点的条件为 false,永远不会满足。这样做就意味着调试器永远不会在这一行上暂停。

关于浏览器调试的30个奇淫技巧

关于浏览器调试的30个奇淫技巧

当你想要豁免某行不受 XHR 断点的影响,忽略正在抛出的异常等情况时,这个功能非常有用。

自动实例 ID

通过在构造函数中设置条件断点来为每个类的实例自动分配唯一 ID:(window.instances = window.instances || []).push(this)

然后通过以下方式检索唯一 ID:window.instances.indexOf(instance)(例如,在类方法中,可以使用 window.instances.indexOf(this))。

Programmatically Toggle

使用全局布尔值来控制一个或多个条件断点的开关。

关于浏览器调试的30个奇淫技巧

然后通过编程方式切换布尔值,例如:

  • 在控制台手动切换布尔值
window.enableBreakpoints = true;
  • 从控制台上的计时器切换全局布尔值:
setTimeout(() => (window.enableBreakpoints = true), 5000);
  • 在其他断点处切换全局布尔值:

关于浏览器调试的30个奇淫技巧

monitor() class Calls

你可以使用 Chromemonitor 命令行方法来轻松跟踪对类方法的所有调用。例如,给定一个 Dog 类:

class Dog {  
    bark(count) {  
        /* ... */  
    }  
}

如果我们想知道对 的所有实例进行的所有调用Dog,请将其粘贴到命令行中:

var p = Dog.prototype;  
Object.getOwnPropertyNames(p).forEach((k) => monitor(p[k]));

你将在控制台中得到输出:

function bark called with arguments: 2

如果您想暂停任何方法调用的执行(而不是仅仅记录到控制台),您可以使用debug而不是monitor

特定实例

如果不知道该类但有一个实例:

var p = instance.constructor.prototype;  
Object.getOwnPropertyNames(p).forEach((k) => monitor(p[k]));

当想编写一个对任何类的任何实例执行此操作的函数(而不仅仅是Dog)时很有用

调用和调试函数

在控制台中调用要调试的函数之前,请调用debugger. 例如给出:

function fn() {  
    /* ... */  
}

从控制台发现:

debugger; fn(1);

然后“Step into next function call”来调试fn.

当不想手动查找定义fn并添加断点或者fn动态绑定到函数并且不知道源代码在哪里时很有用。

Chrome 中,还可以选择debug(fn)在命令行上调用,调试器将fn在每次调用时暂停内部执行。

URL 更改时暂停执行

在单页应用程序修改 URL 之前暂停执行(即发生某些路由事件):

const dbg = () => {  
 debugger;  
};  

history.pushState = dbg;  
history.replaceState = dbg;  
window.onhashchange = dbg;  
window.onpopstate = dbg;

创建一个暂停执行而不中断导航的版本dbg是留给读者的练习。

另请注意,当代码直接调用时,这不会处理window.location.replace/assign,因为页面将在分配后立即卸载,因此无需调试。如果您仍然想查看这些重定向的来源(并调试重定向时的状态),在 Chrome 中您可以使用debug相关方法:

debug(window.location.replace);  
debug(window.location.assign);

读取属性

如果有一个对象并且想知道何时读取该对象的属性,请使用对象 getter 进行调用debugger。例如,转换{configOption: true}{get configOption() { debugger; return true; }}(在原始源代码中或使用条件断点)。

将一些配置选项传递给某些东西并且想了解它们如何使用时,这很有用。

copy()

可以使用控制台 API 将感兴趣的信息从浏览器直接复制到剪贴板,而无需进行任何字符串截断copy()。您可能想要复制一些有趣的内容:

  • 当前 DOM 的快照:copy(document.documentElement.outerHTML)
  • 有关资源的元数据(例如图像):copy(performance.getEntriesByType("resource"))
  • 一个大的 JSON blob,格式为:copy(JSON.parse(blob))
  • 本地存储的转储:copy(localStorage)

在禁用 JS 的情况下检查 DOM

DOM 检查器中按 ctrl+\ (Chrome/Windows) 可随时暂停 JS 执行。这允许检查 DOM 的快照,而不必担心 JS 改变 DOM 或事件(例如鼠标悬停)导致 DOM 从下方发生变化。

检查难以捉摸的元素

假设您想要检查仅有条件出现的 DOM 元素。检查所述元素需要将鼠标移动到它,但是当你尝试这样做时,它就会消失:

关于浏览器调试的30个奇淫技巧 要检查该元素,您可以将其粘贴到控制台中setTimeout(function() { debugger; }, 5000);:这给了你 5 秒的时间来触发 UI,然后一旦 5 秒计时器到了,JS 执行就会暂停,并且没有任何东西会让你的元素消失。您可以自由地将鼠标移动到开发工具而不会丢失该元素:

关于浏览器调试的30个奇淫技巧

当 JS 执行暂停时,可以检查元素、编辑其 CSS、在 JS 控制台中执行命令等。

在检查依赖于特定光标位置、焦点等的 DOM 时很有用。

记录DOM

要获取当前状态下 DOM 的副本:

copy(document.documentElement.outerHTML);

每秒记录一次 DOM 快照:

doms = [];

setInterval(() => {

  const domStr = document.documentElement.outerHTML;

  doms.push(domStr);

}, 1000);

或者将其转储到控制台:

setInterval(() => {

  const domStr = document.documentElement.outerHTML;

  console.log("snapshotting DOM: ", domStr);

}, 1000);

监控元素

(function () {  
    let last = document.activeElement;  
    setInterval(() => {  
        if (document.activeElement !== last) {  
            last = document.activeElement;  
            console.log("Focus changed to: ", last);  
        }  
    }, 100);  
})();

关于浏览器调试的30个奇淫技巧

寻找元素

const isBold = (e) => {
  let w = window.getComputedStyle(e).fontWeight;
  return w === "bold" || w === "700";
};
Array.from(document.querySelectorAll("*")).filter(isBold);

或者只是当前在检查器中选择的元素的后代:

Array.from($0.querySelectorAll("*")).filter(isBold);

获取事件监听器

在 Chrome 中,可以检查当前所选元素的事件侦听器:getEventListeners($0),例如:

关于浏览器调试的30个奇淫技巧

监听元素事件

调试所选元素的所有事件:monitorEvents($0)

调试所选元素的特定事件:monitorEvents($0, ["control", "key"])

关于浏览器调试的30个奇淫技巧

点赞收藏支持、手留余香、与有荣焉,动动你发财的小手哟,感谢各位大佬能留下您的足迹。

关于浏览器调试的30个奇淫技巧

往期热门精彩推荐

面试相关热门推荐

实战开发相关推荐

移动端相关推荐

Git 相关推荐

转载自:https://juejin.cn/post/7345297230201716776
评论
请登录