4

I have a js script with a console.log that sometimes prints html elements.

Chrome has two modes of printing such DOM elements:

  • In html style like <div class="abc">...</div>, where hovering highlights the element in the page, and click opens the DOM subtree.
  • In object style like div.abc, where hovering does nothing, and click opens the object properties.

I always want the first format.

But for some reason, when printing a lot of these elements, Chrome randomly switches to the second format.

At first I thought this happens if there is not enough space, e.g. if we print other values in the same console.log call. But this seems not to be the case.

Any idea how I can always get the first format? Either a setting in Chrome/Chromium, or something I can do in my script.

EDIT

I will try to come up with a reproducible example. It will be difficult because this happened on a website with already a lot going on.

For now I will simply mention that by "a lot of these elements", I mean repeated calling of console.log(element) with different elements. The first 100 or so calls would give me the first representation, then it would switch to the other representation. But this was not at all consistent, and there was no specific event that would explain such a switch.

New data points since initial version of the question:

  • console.dirxml(element) also switches to the JSON prepresentation (= second format), at the same time that console.log does.
  • console.log(element, element instanceof HTMLElement) always prints [element], true, no matter whether the json or xml representation is used to print the element.
donquixote
  • 4,877
  • 3
  • 31
  • 54

3 Answers3

3

You cannot get always this format because that is unpredictable in the blink engine, and the source code is the proof, moreover there is a comment exactly for this case:

function printNode(nodeId)
{
    if (!nodeId) {
        // Sometimes DOM is loaded after the sync message is being formatted, so we get no
        // nodeId here. So we fall back to object formatting here.
        this._formatParameterAsObject(object, elem, false);
        return;
    }
n--
  • 3,563
  • 4
  • 9
  • Wow, this is a great answer! I wonder how we might reproduce this scenario. In my own example, the elements already exist and are part of the DOM, before the code runs. But perhaps the browser gets overwhelmed and confused, and perhaps what matters is not the actual DOM but the representation of the object in the developer tools. – donquixote Aug 16 '22 at 23:03
  • Btw you might want to answer here, https://stackoverflow.com/questions/71034045/google-chromes-console-log-prints-dom-nodes-inconsistently, then we can close this one as duplicate. – donquixote Aug 16 '22 at 23:04
  • @donquixote I did, but actually I think there is a subtle difference in these two questions, yours being about "how" and another about "why", but in the end you decide ;) – n-- Aug 18 '22 at 16:38
2

for some reason, when printing a lot of these elements, Chrome randomly switches to the second format

Without a minimal, reproducible example demonstrating both cases, it's hard to provide a fully-satisfying answer, but according to the documentation, the following methods will print the XML representation of a node:

While, in contrast, console.dir(node) will print a JSON representation of the node.

There is also a console utility function for navigating (programmatically focusing) a node/object: inspect(object/function).


If, by "printing a lot of these elements" you just mean an object collection like an Array or NodeList, then that's not a level of display control that Chromium's dev tools offers you. Instead, you should iterate each node and print it (or provide each node as an argument to console.log, for example:

const divArray = [...document.querySelectorAll('div')];
console.log(divArray); // JSON representation of an array (of div elements)
console.log(...divArray); // one XML representation for each div element
jsejcksn
  • 27,667
  • 4
  • 38
  • 62
  • Do you know why this changes at random when using `console.log`? – Konrad Aug 16 '22 at 18:55
  • [^](https://stackoverflow.com/questions/73378465/always-reveal-html-element-in-console-log-chromium/73378935?noredirect=1#comment129587181_73378935) @KonradLinkowski What do you mean by "this changes at random"? – jsejcksn Aug 16 '22 at 18:56
  • So I tried to reproduce the OP's issue a second ago and it seems like, first logging an HTML element to the console and then opening the dev tools results in `xml` type of logging. First opening the dev tools and then logging results in `json` type of logging. – Konrad Aug 16 '22 at 19:09
  • [^](https://stackoverflow.com/questions/73378465/always-reveal-html-element-in-console-log-chromium/73378935?noredirect=1#comment129587435_73378935) @KonradLinkowski The OP didn't provide any reproduction info, so — according to [the way that it's currently written](https://stackoverflow.com/revisions/73378465/1) — it's not certain what they mean. You are welcome to [ask a new question](https://stackoverflow.com/questions/ask) if you have a [reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) (or unambiguous reproduction steps) to include in it. – jsejcksn Aug 16 '22 at 19:15
  • 1
    @KonradLinkowski For me the console was open all the time. But perhaps you found another scenario that forces this kind of switch. – donquixote Aug 16 '22 at 20:48
  • 1
    https://stackoverflow.com/questions/73379385/why-is-console-logs-format-inconsistent-when-printing-html-element-in-chromes – Konrad Aug 16 '22 at 20:53
  • 1
    Thanks @KonradLinkowski. Yours is marked as duplicate and links to https://stackoverflow.com/questions/71034045/google-chromes-console-log-prints-dom-nodes-inconsistently – donquixote Aug 16 '22 at 21:09
0

One way can be to log the HTML element as a string using the Element.outerHTML property, e.g.

const myDiv = document.querySelector('#myDiv');

console.log(myDiv.outerHTML); // <div id="myDiv"></div>

Or console logging only after the page has loaded, using the window.onload event handler property, e.g.

onload = (e) => console.log(myDiv);

...which I prefer since it prints the actual HTML element to the console, like:

<div id="myDiv"></div>
Ian
  • 27
  • 5