preface

This is a reading of notes and reflections on the Nuggets of Chrome Debugging Tips You Didn’t know.

This booklet documents some useful techniques that may be less well known. On this basis, I screened out some skills I did not know before, partial to the personal, can read the original volume.

Of course, if you’ve read the entire Chrome-DevTools series, you probably know all of these tips.

In addition to the list of techniques, this article will add some reflections on what problems this technique is used to solve and how other browsers can simulate implementation.

General article

1. copy(value)

Call the global copy method to copy the value to the clipboard

Before we do that, we want to copy the value of an object, what do we do? The clumsy approach may be to output it, and then layer upon layer, copy and then remove some useless or duplicate text (understand all understand); Or, to be more clever, use json.stringify (val,null,2) with indentation and then copy

However, now you just need the copy method to copy quickly.

Borrow the original figure

Json.stringify (val,null,2) is called internally when stringify(val,null,2) is copied to [object object].

let a = {say:() = >{},name:'gahing'}
copy(a) // {name:'gahing'}
a.toJSON = () = >1
copy(a) / / 1
a.c=a
copy(a) // [object Object]
Copy the code

So, for other browsers, you can also write a global copy method for use:

window.copy = (val) = > {
    const getData = (val) = > {
        if (val instanceof Element) {
            return val.innerHTML
        }
        try {
            return JSON.stringify(val, null.2)}catch (error) {
            return '[object Object]'}}const writePasterVersion = (data) = > {
        // Use textarea to preserve newlines and so on
        const textarea = document.createElement('textarea')
        document.body.appendChild(textarea)
        textarea.setAttribute("readonly".true)
        textarea.value = data
        textarea.select()
        if (document.execCommand('copy')) {
            document.execCommand('copy')}document.body.removeChild(textarea)
    }
    const data = getData(val)
    writePasterVersion(data)
}
Copy the code

Note that there is also a copy of the content of the DOM element, which is also supported by the original copy method. However, dom copying is also supported by most browsers.

2. The shortcut key

This article, and others, mention keyboard shortcuts.

This one doesn’t have to be memorized too much, so just open the Shortcuts panel (open the console => press F1=> cut to the Shortcuts panel) and use it for a while.

Or see The Google Dev article -> keyboard shortcut reference

Start DevTools>>Settings >>Preferences>>Appearance to open this option:

As an added bonus, the old Cmd + numeric shortcut keys are more useful and can be used to cut tabs, which is great for work.

3. Use the Command

For those of you who have used VS Code, you can use Cmd + Shift + P to raise the Command menu. In fact, the browser does the same thing (you need to open developer tools first).

The features included are:

The picture above is taken from the booklet

Most commands are generic Settings and actions. You can actually find Settings and shortcuts in Settings, so most of them are useless. Here are two commands that I personally think are irreplaceable

(1) Debugger – disable JavaScript

You can also find the corresponding Settings in settings-preferences.

We should often encounter the requirement that a floating window appears when the mouse moves over an area and disappears when the mouse moves away. The display and hiding of the floating window is controlled by the js mouse event. What if we want to debug the FLOAT window DOM structure?

The following operations have been tried before:

  1. Right-click – check the DOM that is located in the Elements panel, and use Tab and arrow keys to debug styles. Manipulation is limited, and floating Windows often disappear accidentally, resulting in white debugging.
  2. To open the firstSettings - PreferencesPanel, when the mouse pointer appears to float, quickly cut to the Preferences panel for Settingsdisable JavaScriptHowever, this requires a good Angle and hand speed, the success rate is not high.

Today, I found that you can cut out the Command panel in advance, focus on the input box, and then move the mouse to the corresponding area to display the floating window. On the other hand, the Command panel type Disable JavaScript and press Enter to Disable JS, and you can do whatever you want

20200915 Update: This solution does not handle clicking cases (such as clicking a selection box to display a drop-down list). After advice from colleagues, I provided other solutions:

  1. settimeout debugger
  2. The Elements panel -> Parent element Break on -> Subtree modifications

(2) Screentshot command screenshot

Type in Screentshot and you’ll see the following command:

  • Capture Area Screentshot: Select a rectangular area and take screenshots
  • Capture full size Screentshot
  • Capture node Screentshot: Capture a node area separately. You need to go to the Elements panel to select the node before executing this command.
  • Capture Screentshot: Capture the viewable area of the current page

These four commands can basically meet our various needs for static screenshots of the web page, some Chrome extensions can choose to uninstall ~

4. Use of Snippets

We often write temporary test code on the console. But you might have to use it again a long time later, so it’s kind of a waste of time to rewrite it again.

Chrome gives us the ability to write snippets of code that can then be executed anytime, anywhere (on any page).

We can create a new snippet in the Snippets bar in the Sources panel and run it by right-clicking run or Cmd + Enter

The picture above is taken from the booklet

You can even use Cmd + P to cut Open file and enter! Then select snippet and press Enter to run the snippet

The picture above is taken from the booklet

A few usage scenarios that can be thought of are:

  1. Write single-test or interface test code based on FETCH
  2. Write common tool methods
  3. Import the UMD CDN script address of some NPM package (such as moment/loadsh, etc.) to the page and test the functionality of the NPM package
  4. Do breakpoint testing (covered below)

For me, though, this feature is a bit of a chicken. On the one hand, it is rarely used, and on the other hand, there are various alternatives, such as typing a few keywords console and jumping out of the history of input.

And the actual Snippets data can’t be synced between Chrome, which would be more useful if it were, and you can build your own library.

The console article

Most of these tips can be found in the Chrome DevTools Console article

1. $in the console

$0 to $4

$0 represents a reference to the currently selected node, $1 represents an introduction to the last selected node, and so on up to $4

So we can move dom nodes very easily

<div class="list">
  <div class="item"></div>
  <div class="item"></div> <! $1 -->
</div>
<div class="content"></div> <! $0 -->
Copy the code

application

$1.appendChild($0) // The dom node can be moved
Copy the code

The $$$

$is equivalent to the document.querySelector alias

$$is similar to the document. QuerySelectorAll, but returns the node array, rather than a NodeList class array object

$and $$also support the second parameter startNode, which is the query starting point document changed to startNode

$("div", $("div"))
Copy the code

Simple mocks from other browsers (without exception handling and special judgments)

window$=(selector, startNode) = > (startNode || document).querySelector(selector)

window.$$ = (selector, startNode) = > Array.from((startNode || document).querySelectorAll(selector))
Copy the code

The $_

A reference to the result of the last execution

The picture above is taken from the booklet

Other browsers don’t mock. But this function is also quite chicken ribs

$i

Prior to this, console debugging NPM packages is a pain point where we might:

  • Create a new project -> install the NPM package -> package the input into an HTML page -> DevTools test, or
  • Find the UMD package address -> Script import -> DevTools test

Now, you simply need to import the NPM package by executing $I (nPM_package_name) on the console

Strictly speaking, this is a Chrome extension of the function of the Console Importer, not devTools built-in. This means you need to install the extension first, which inserts the $I method globally.

The sample

The picture above is taken from the booklet

However, there is a slight lack of experience in using it: there is no telling which variable is mounted on the window after it is introduced

Because some packages don’t necessarily mount variables that are NPM package names, such as _ of loadsh. This can probably be done by comparing mount variables before and after Windows

At the same time, it is expected to support the import of NPM packages on the Intranet, possibly by specifying the repository source or UMD address

The project address of this expansion is console-importer. I just happened to be studying the browser plug-in recently. You can ask pr for the above two questions when you are free

TODO: There will be another article in the future implementation

2. Ninja console.log

Conditional breakpoints

This is useful for me. Breakpoints are only entered when an expression is satisfied, which is good for conditional breakpoint debugging in looping code

Operation:

  1. Right-click the line number and select Add Conditional BreakPoint… (Add conditional breakpoint)
  2. The expression will not be paused when falsy is returned

The picture above is taken from the booklet

Do we need to create a new HTML document and import script to play if we just want to experience this feature?

No, remember Snippets from above, which also supports debugging, so create a new snippet and start experimenting

// Code snippet
let res = 0
Array.from(Array(15))
.map(Math.random)
.forEach((v,i) = >{
    res += v*i
})
console.log(res)

// Breakpoint expression
v>0.8
Copy the code

The ninja console.log

As mentioned above, the expression will not be paused when the result is falsy, which means we can use code like console.time/log/group as an expression that will not affect the breakpoint flow, but will output normally.

There is no need to enter the console code in the source code anymore

The picture above is taken from the booklet

There is also a logpoint operation, which is to write parameters directly to the expression and output them to the console

So the above console-related operations are also available via LogPoint and are more semantically relevant

3. Method proxy

When a method is called, we can do a number of things, including debugging, input and output arguments, and so on

Write a method

function add(x,y){
  return x+y
}
Copy the code

Debug Debugging methods

How do you debug this method?

perform

debug(add)
Copy the code

The debug panel is brought in when the method is called

add(1.2)
Copy the code

Call debugging can be cancelled with undebug

So to debug a method, we just need to know the name of the method, not where in the code to set the breakpoint.

Implementation of the method:

window.debug = function (fnName, ctx = window) {
    let originFn = ctx[fnName]
    ctx[fnName] = function (. res) {
        debugger
        originFn.apply(ctx, res)
    }
}
Copy the code

The test case

class Animal {
  constructor(name){
    this.name = name
  }
  eat(food){}}let cat = new Animal("cat")
// debug(cat.eat)
debug('eat', cat)
cat.eat("fish")
Copy the code

Unlike the original debug method, we need an explicit incoming context and method name. It takes a couple of moves to get to eat while you’re in the debugger

If there is a better implementation, welcome to share ~

Later, I will have a chance to see how the Command API is handled, and whether it can be implemented by using only JS capabilities

Monitor listens for method calls

We want to know if the code we’re writing gets called and what the input arguments are. In the past we might have written console.log code, but with monitor we don’t need it anymore

monitor(add)
add(1.2)
// output: 
// function add called with arguments: 1, 2
/ / 3
Copy the code

Implementation of the method:

window.monitor = function (fnName, ctx = window) {
    let originFn = ctx[fnName]
    ctx[fnName] = function (. res) {
        console.log(`function add called with arguments: ${res.join(', ')}`)
        return originFn.apply(ctx, res)
    }
}
Copy the code

Disadvantages of the same, there is a better way to welcome to share ~

MonitorEvents (Object [, Events]) listens for event invocations

monitorEvents(window."resize");
Copy the code

Execute the code above and output the following when the window size changes

Resize Event {isTrusted: true, type: "resize", Target: Window, currentTarget: Window, eventPhase: 2,... } resize Event {isTrusted: true, type: "resize", target: Window, currentTarget: Window, eventPhase: 2,... } resize Event {isTrusted: true, type: "resize", target: Window, currentTarget: Window, eventPhase: 2,... } resize Event {isTrusted: true, type: "resize", target: Window, currentTarget: Window, eventPhase: 2,... }Copy the code

Event also support array and mapping, more can see developers.google.com/web/tools/c…

To mock, use addEventListener directly

4. Live Expression

Open it at the “Eyes” symbol in the Console panel.

Analogous to computed in Vue, you write an expression that updates the results in real time as the member variables in the expression change.

Example:

The picture above is taken from the booklet

The usage scenarios in mind are as follows:

(1) Dom node number statistics

document.querySelectorAll("*").length
Copy the code

(2) Calculate mathematical expressions

Math.pow(2,n) + 1
Copy the code

(3) Display the coordinates of the current click position

// The console enters first
document.addEventListener("click".({clientX,clientY}) = >myPosition=({clientX,clientY}))

/ / Live for expression
myPosition // The effect is similar to the above example, which is not shown here
Copy the code

other

  • Console panel can use await directly without wrapping async iife
  • When testing callback parameters, use them directly in the callbackconsole.logBetter to do:getLocation(console.log)And don’tgetLocation((v)=>console.log(v))

The Network article

1. Close the Overview function to expand the request panel space

An overview is some timeline information that we don’t need in most cases and takes up space on the panel

You can turn it off in Settings (show Overview above)

2. Disable the request

Want to see what a web page looks like when certain scripts, style files are missing, or other resources fail to load? Right-click on a Request in the Network panel and select the Block Request URL. A new disabled request panel is called out, where disabled requests can be managed.

(Above quoted from official text)

It’s easier to set URL rules in the Disable Requests panel, which also supports regex

3. The XHR/fetch the breakpoint

On the right side of the Source panel, XHR/ Fetch Breakpoints creates a breakpoint

The following is an example:

The picture above is taken from the booklet

For example, make a breakpoint on a form submission request to see if the submitted data is healthy (you can also see the data in the Network panel).

No necessary usage scenarios have been found for this feature

The Elements panel piece

1. ByhHide elements

Select the element and press H to hide it by adding a style to it

visibility: hidden ! important;
Copy the code

Pressing again displays the element

2. Contrast ratio of color pickers

Open the color selector for the text, and you see the Contrast Ratio property, which represents the Contrast between the text color and the background color

There are three cases:

  1. 🚫 : the contrast is too low
  2. ✅ : complies with the AA statement. The value must be at least 4.5
  3. ✅✅ : the value must be at least 7

The picture above is taken from the booklet

When Contrast Ratio is expanded, two lines appear in the color palette to guide the developer in selecting Contrast that meets the appropriate criteria

The Drawer article

Open the file using More Tools

The entrance is deeper because it’s used less. Here’s the next useful new feature.

1. Changes

We often style our online pages on the console.

How do I know which styles I changed when debugging is over? The human brain?

At this point, the Changes function can meet our needs

It keeps track of changes to files, just like Git, and allows you to undo some changes

The picture above is taken from the booklet

However, it is important to note that this Changes feature is useless for compressed CSS with only one line of style

The Workspace article

For the most part, we developed with frameworks and packaging tools, which didn’t work very well (or my posture was wrong) and won’t be covered here.

This feature may be useful for small pure JS/CSS projects

In a word, changes are synchronized

conclusion

Chrome Devtools offers a lot of great features and solves a lot of pain points, but some features are weak

Devtools features are constantly being updated, and just reading other people’s articles isn’t enough to make you the best Debug boy. You need to read the official documentation 😏