✨Chrome DevTools 使用指☞北 - 来源面板之断点的使用 🔔

649 阅读7分钟

使用断点暂停代码 🌈

暂停时检查值 🐾

  • 新建一个 代码段,将下面内容粘贴到工作区。

    function values() {
      let string = 'I\'m a string'; 
      const number = 42;
      let bool = 42 > 0;
      let player = { 
          "name": "Parzival",
          "number": 1,
          "state": "ready",
      };
      let array = [1,2,3];
      debugger;
    }
    values();
    

    image.png

  • 按下 Ctrl + S 保存代码,之后按下 Ctrl + Enter 执行代码

    image.png

  • 执行暂停时,调试程序会展示当前函数中的所有变量、常量和对象

    image.png

  • 您可以使用 控制台 查询已求值的变量、常量和对象

    image.png

悬停时预览类/函数属性 🐾

  • 新建一个 代码段,将下面内容粘贴到工作区。

    class Person {  
      constructor(name, age) {  
        this.name = name;  
        this.age = age;  
      }  
    
      sayHello() {  
        console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);  
      }  
    }  
    
    const person = new Person('Tom', 30);  
    person.sayHello();
    
  • 执行暂停时,将鼠标悬停在类或函数名称上可预览其属性。

    image.png

不同断点类型的使用 🌈

每种断点类型的使用时机概览 🐾

断点类型如果您想执行以下操作 ...
代码行暂停特定的代码区域。
条件代码行暂停特定的代码区域,但仅当其他一些条件为 true 时才暂停。
日志点在不暂停执行的情况下将消息记录到控制台
DOM暂停在更改或移除特定 DOM 节点或其子节点的代码上。
XHR当 XHR 网址包含字符串模式时暂停。
事件监听器暂停在事件(如 click)触发后运行的代码。
异常在抛出已捕获或未捕获异常的代码行暂停。
功能在每次调用特定函数时暂停。
可信类型暂停信任类型违规行为。

代码行断点 🐾

如需在开发者工具中设置代码行断点,请执行以下操作:

  1. 点击来源面板。

  2. 打开包含您想要换行的代码行的文件。

  3. 转到代码行。

  4. 代码行的左侧是行号列。点击该图标。屏幕上会出现一个蓝色图标 行号列的顶部。

    代码行断点。

代码中的代码行断点 🎈
  • 在代码中调用 debugger 即可暂停到该行

    console.log('a');
    console.log('b');
    debugger;
    console.log('c');
    
条件代码行断点 🎈
  • 假设您有以下 JavaScript 代码:

    function printSquares(numbers) {  
        for (let i = 0; i < numbers.length; i++) {  
            console.log(numbers[i] * numbers[i]);  
        }  
    }  
    
    // 假设我们有一个数字数组  
    const nums = [1, 2, 3, 4, 5];  
    printSquares(nums);
    
  • 步骤:

    1. 找到 console.log(numbers[i] * numbers[i]); 这一行。

    2. 点击行号以设置断点。

    3. 右键点击该断点,选择“编辑断点”(Edit Breakpoint)。

    4. 在弹出的框中输入条件,例如 numbers[i] > 3

      image.png

    5. 继续运行代码,当 numbers[i] 大于 3 时,代码执行将暂停。

      image.png

记录代码行断点 🎈
  • 假设您有以下 JavaScript 代码:

    function calculateSum(numbers) {  
        let sum = 0;  
        for (let i = 0; i < numbers.length; i++) {  
            sum += numbers[i];  
        }  
        return sum;  
    }  
    
    // 测试数组  
    const nums = [1, 2, 3, 4, 5];  
    const total = calculateSum(nums);  
    console.log("Total sum:", total);  
    
  • 步骤:

    1. 找到您想要添加日志点的代码行(例如,sum += numbers[i];)。

    2. 右键点击该行的行号,然后选择“添加日志点”(Add Logpoint)。

    3. 在弹出的输入框中输入您想要记录的消息,例如:

      `Adding number: `, numbers[i]  
      

      这里的 {numbers[i]} 是占位符,将在日志点触发时被实际值替换。

      image.png

    4. 代码执行后的结果

      image.png

修改代码行断点 🎈

Breakpoints 部分按文件对断点进行分组,并按行号和列号对其进行排序。您可以对群组执行以下操作:

  • 要收起或展开某个组,请点击其名称。

  • 如需单独启用或停用某个组或断点,请点击该组或断点旁边的 ✅。

  • 如需修改断点,点击 🖊 进行修改

  • 要移除某个组,请将鼠标悬停在其上方,然后点击 ❌。

    image.png

断点部分中,右键点击某个组,会有如下选择

image.png

DOM 更改断点 🐾

  1. 点击Elements标签页。

  2. 转到要设置断点的元素。

  3. 右键点击相应元素。

  4. 将鼠标悬停在划分点上,然后选择子树修改属性修改或 节点移除

    image.png

您可以在以下位置找到 DOM 更改断点列表:

  • Elements >DOM Breakpoints 窗格。

    image.png

  • 来源 >DOM 断点侧窗格。

    image.png

在该页面中,您可以:

  • 您可以通过 ✅ 启用或停用这些控件。
  • 右键点击 > 在 DOM 中移除显示它们。
DOM 更改断点的类型 🎈
  • 子树修改。当当前所选节点的子级被移除或 或更改子元素的内容。未在子节点属性更改时触发,或 对当前所选节点进行任何更改。
  • 属性修改:在 当前选定的节点时,或当属性值发生更改时。
  • 节点移除:在移除当前选定的节点时触发。

XHR/提取断点 🐾

  • 如果要在 XHR 的请求网址包含指定的字符串。DevTools 会在 XHR 调用 send() 的代码行暂停。

  • 举例来说,如果您发现自己的网页请求的是错误的网址, 而您希望快速找到导致错误请求的 AJAX 或 Fetch 源代码。

  • 代码示例:

    <!DOCTYPE html>  
    <html lang="en">  
    <head>  
        <meta charset="UTF-8">  
        <meta name="viewport" content="width=device-width, initial-scale=1.0">  
        <title>XHR Example</title>  
        <style>  
            body {  
                font-family: Arial, sans-serif;  
            }  
            #data {  
                margin-top: 20px;  
            }  
        </style>  
    </head>  
    <body>  
    
    <h1>XMLHttpRequest 示例</h1>  
    <button id="fetch-button">获取数据</button>  
    <div id="data"></div>  
    
    <script>  
        document.getElementById('fetch-button').addEventListener('click', function() {  
            // 创建新的 XMLHttpRequest 对象  
            var xhr = new XMLHttpRequest();  
    
            // 设定请求类型和目标 URL  
            xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', true);  
    
            // 注册事件处理程序来处理响应  
            xhr.onload = function() {  
                if (xhr.status >= 200 && xhr.status < 300) {  
                    // 请求成功,处理返回的数据  
                    var response = JSON.parse(xhr.responseText);  
                    document.getElementById('data').innerHTML = `  
                        <h2>${response.title}</h2>  
                        <p>${response.body}</p>  
                    `;  
                } else {  
                    // 请求失败,处理错误  
                    console.error('请求失败,状态码:', xhr.status);  
                    document.getElementById('data').innerHTML = '请求失败,请查看控制台输出。';  
                }  
            };  
    
            // 注册事件处理程序来处理请求错误  
            xhr.onerror = function() {  
                console.error('请求由于网络错误而失败。');  
                document.getElementById('data').innerHTML = '请求失败,请查看控制台输出。';  
            };  
    
            // 发送请求  
            xhr.send();  
        });  
    </script>  
    
    <!-- Code injected by live-server -->
    <script>
            // <![CDATA[  <-- For SVG support
            if ('WebSocket' in window) {
                    (function () {
                            function refreshCSS() {
                                    var sheets = [].slice.call(document.getElementsByTagName("link"));
                                    var head = document.getElementsByTagName("head")[0];
                                    for (var i = 0; i < sheets.length; ++i) {
                                            var elem = sheets[i];
                                            var parent = elem.parentElement || head;
                                            parent.removeChild(elem);
                                            var rel = elem.rel;
                                            if (elem.href && typeof rel != "string" || rel.length == 0 || rel.toLowerCase() == "stylesheet") {
                                                    var url = elem.href.replace(/(&|\?)_cacheOverride=\d+/, '');
                                                    elem.href = url + (url.indexOf('?') >= 0 ? '&' : '?') + '_cacheOverride=' + (new Date().valueOf());
                                            }
                                            parent.appendChild(elem);
                                    }
                            }
                            var protocol = window.location.protocol === 'http:' ? 'ws://' : 'wss://';
                            var address = protocol + window.location.host + window.location.pathname + '/ws';
                            var socket = new WebSocket(address);
                            socket.onmessage = function (msg) {
                                    if (msg.data == 'reload') window.location.reload();
                                    else if (msg.data == 'refreshcss') refreshCSS();
                            };
                            if (sessionStorage && !sessionStorage.getItem('IsThisFirstTime_Log_From_LiveServer')) {
                                    console.log('Live reload enabled.');
                                    sessionStorage.setItem('IsThisFirstTime_Log_From_LiveServer', true);
                            }
                    })();
            }
            else {
                    console.error('Upgrade your browser. This Browser is NOT supported WebSocket for Live-Reloading.');
            }
            // ]]>
    </script>
    </body>  
    </html>
    
  • 如需设置 XHR/fetch 断点,请执行以下操作:

    1. 点击来源面板。

    2. 展开 XHR Breakpoints 窗格。

    3. 点击 ➕ Add breakpoint

    4. 输入要换行的字符串。出现此字符串时,开发者工具会暂停 XHR 请求网址中的任意位置。

    5. 按 Enter 键进行确认。

      image.png

    6. 点击获取数据,DevTools 会在 XHR 调用 send() 的代码行暂停。

      image.png

事件监听器断点 🐾

  • 如果要暂停在某事件监听器代码之后运行的事件监听器代码,可以使用事件监听器断点 事件。您可以选择特定事件例如 click

  • 示例代码:

    <!DOCTYPE html>  
    <html lang="en">  
    <head>  
        <meta charset="UTF-8">  
        <meta name="viewport" content="width=device-width, initial-scale=1.0">  
        <title>事件监听器断点测试</title>  
    </head>  
    <body>  
        <h1>事件监听器断点示例</h1>  
        <button id="myButton">点击我</button>  
    
        <script>  
            // 添加按钮的点击事件监听器  
            document.getElementById('myButton').addEventListener('click', function() {  
                console.log('按钮被点击了!');  
                // 在这里添加一些复杂的逻辑以便调试  
                performComplexOperation();  
            });  
    
            function performComplexOperation() {  
                console.log('执行复杂操作...');  
                let sum = 0;  
                for (let i = 0; i < 1000000; i++) {  
                    sum += i;  
                }  
                console.log('复杂操作完成,结果是:', sum);  
            }  
        </script>  
    </body>  
    </html>
    
  • 在事件监听器断点中选择 Mouse 中的 Click,点击 点击我

    image.png

异常断点 🐾

  • 遇到未捕获的异常时暂停

    function divideNumbers(x, y) {  
        if (y === 0) {  
            throw new Error("Cannot divide by zero");  
        }  
        return x / y;  
    }  
    
    function main() {  
        const num1 = 10;  
        const num2 = 0; // 这是将触发异常的输入  
        console.log("结果是:", divideNumbers(num1, num2));  
    }  
    
    main();
    

    image.png

  • 在遇到异常时暂停

    function riskyOperation(x, y) {  
        if (y === 0) {  
            throw new Error("Cannot divide by zero");  
        }  
        return x / y;  
    }  
    
    async function main() {  
        const num1 = 10;  
        const num2 = 0; // 这是将触发异常的输入  
    
        try {  
            const result = riskyOperation(num1, num2);  
            console.log("结果是:", result);  
        } catch (error) {  
            console.error("捕获到异常:", error.message);  
        }  
    }  
    
    main();  
    

    image.png

函数断点 🐾

  • 当您需要调试时,调用 debug(functionName),其中 functionName 是您要调试的函数,使用 debug 会在每次调用特定函数时暂停。debug()相当于设置函数第一行上的代码行断点

  • 示例:

    function sum(a, b) {
      let result = a + b; // DevTools pauses on this line.
      return result;
    }
    debug(sum); // Pass the function object, not a string.
    sum();
    

    image.png