75

Using jQuery I can easily get the number of DOM elements used by a web page:

$('*').length;

But not all web sites are using jQuery.

So my question is: How do I get the number of DOM elements used in a web page using pure JavaScript and js console.

antonjs
  • 14,060
  • 14
  • 65
  • 91

5 Answers5

135

Assuming you mean "HTMLElementNodes" as opposed to "All nodes" (which would include such things as text nodes and also be skipped by your jQuery example) then:

document.getElementsByTagName('*').length

This still requires the use of DOM though. Pure JavaScript can't interact with an HTML document other than as a string of text.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 1
    nice. I've just created a bookmarklet based on that: https://github.com/lingtalfi/count-dom-nodes-bookmarklet – ling Sep 23 '16 at 20:00
  • upvoted! how would you get how many nodes by tag? like a 1500 p 2100 etc – PirateApp Aug 21 '20 at 10:21
  • @ling Courtesy of your github bookmark I made a question that is related to and continues from your original work: https://stackoverflow.com/q/72531897/509670 – Sam Jun 07 '22 at 13:26
29

It's quite simple really:

document.getElementsByTagName('*').length

If you can ignore older browsers, you could also preserve some of the jQuery-like syntax with:

var $;
$ = document.querySelectorAll.bind(document);
$('*').length;
zzzzBov
  • 174,988
  • 54
  • 320
  • 367
  • 2
    `querySelectorAll` needs `this` to be `document`. You can't successfully call it without the context of the `document` object so that code will fail (in Chrome at least). – Quentin Mar 21 '12 at 16:10
  • 4
    whoops, forgot to add `bind`. – zzzzBov Mar 21 '12 at 16:11
  • The bind/context requirement isn't there anymore. You can just call document.querySelectorAll and it works. Every node has that function and calling it on a node calls it in that context. – Advait Junnarkar Feb 05 '20 at 22:46
  • 2
    @Advait Junnarkar `bind` was used to alias the query to `$`. It had never been necessary via `document.querySelectorAll`. – zzzzBov Feb 06 '20 at 14:25
  • @zzzzBov That makes sense. I misunderstood the answer. – Advait Junnarkar Feb 07 '20 at 01:07
8

This question is the top result on google for "js count all dom nodes" but it's 2021 now and we have ShadowDOM so none of these previous answers will actually give an accurate result.

Better to use this function which is based on the code used by Lighthouse to calculate the true DOM size.

function countNodes(element = document.body) {
  let count = 0; let child = element.firstElementChild;    
  while (child) { count += countNodes(child);
    if (child.shadowRoot) { count += countNodes(child.shadowRoot); }
    child = child.nextElementSibling; count++;
  } return count;
}
Besworks
  • 4,123
  • 1
  • 18
  • 34
3

Using a recursive function countChildrenNumber:

function countChildrenNumber(el) {
  let result = 0
  if (el.children && el.children.length > 0) {
    result = result + el.children.length
    for (let i = 0; i < el.children.length; i++) {
      result = result + countChildrenNumber(el.children[i])
    }
  }
  return result
}

then call it by passing document as the parameter

countChildrenNumber(document)
yunfu wang
  • 31
  • 2
-3

The main answer doesn't really count everything (I think shadow DOM would be excluded)

Using snippet below works better for me:

$$('*').length
dzh
  • 286
  • 1
  • 19