Search code examples
javascriptdomgoogle-chrome-extensioncontent-script

getElementsByClassName behaves strangely in chrome extension content script


I've created a content script that does the following:

  var stuff = document.getElementsByClassName("actual-log");
  console.log(stuff);
  console.log(stuff[0]);
  console.log(stuff.length);

I get the following output:

HTMLCollection []0: div.actual-log1: div.actual-log2: div.actual-log3: div.actual-log4: div.actual-log5: div.actual-log6: div.actual-log7: div.actual-log8: div.actual-log9: div.actual-log10: div.actual-log11: div.actual-log12: div.actual-log13: div.actual-log14: div.actual-log15: div.actual-log16: div.actual-log17: div.actual-log18: div.actual-log19: div.actual-log20: div.actual-log21: div.actual-loglength: 22__proto__: HTMLCollection
main.js:4 undefined
0

This output seems totally impossible to me. In the first line it is clear that a bunch of results were returned, and that the HTMLCollection that is returned clearly has length 22. The subsequent lines are totally inconsistent with this.

What is going on here?


Solution

  • What you experience is that getElementsByClassName returns a DynamicNodeList, meaning it is live and changes to the DOM will be automatically reflected in the collection.

    In contrast, using querySelectorAll will return a StaticNodeList, which is like a snapshot of the DOM at the time the query took place. Any changes that happens after the query will no be reflected in the collection it returns.