No Mod Required

A static variation on JavaScript’s getElementsByTagName

As I mentioned yesterday I wanted to offer up an alternative to the browser crushing example I made to illustrate the point about Javascript Objects. So here it is…

Instead of using getElementsByTagName("a") and watching the count grow towards infinity, I simply added a new function which does the same thing as getElementsByTagName, except that it takes a "snapshot" of the nodeList and turns it into a plain old Array. So, unlike a variable created with getElementsByTagName, this one will not track changes to the underlying DOM collection.* I’ve illustrated this with a count of the members of the two collections before and after the manipulations are run.

Here’s a sample:

And here’s the function

function getStaticCollectionByTagName(tag, node) {
  //just like getElementsByTagName, we want to open up and optional context node 
  if (node==undefined) {
  //if it's not passed in as an argument, we set it to be document 
  node=document
  }
  //we build a variable with the original collection 
  var temp_array = node.getElementsByTagName(tag);
  //and a new array to hold them 
  var static_results = new Array;
  //then we just loop through and copy each into the new array 
  for (i=0; i<temp_array.length;i++) {
  static_results.push(temp_array[i]);
  }
  //and return it 
  return static_results;
  }

As a note, feel free to comment on any/all of the code articles I write here. I’m mostly writing this stuff to push my own knowledge and understanding so if you see something I can do better, something that I’ve missed or something that’s just plain silly, feel free to let me know :)

*it WILL track the individual objects that make up the collection as those are passed to the new array as Object references.

2 Responses to “A static variation on JavaScript’s getElementsByTagName”

  1. James Says:

    Thanks for this. I ran into the exact same issue. It’s baffling that all_links would be the reference to the function. Totally unintuitive.

  2. rob Says:

    I think the problem is that most people (like 99% of people) just think of the result of using getElementsByTagName as being an array. It acts like an array in the way most people use it so that idea works most of the time. Thing is, it’s not an array, but a NodeList, which is defined to work that way:

    The DOM also specifies a NodeList interface to handle ordered lists of Nodes, such as the children of a Node, or the elements returned by the Element.getElementsByTagName method… NodeLists and NamedNodeMaps in the DOM are “live”, that is, changes to the underlying document structure are reflected in all relevant NodeLists and NamedNodeMaps. For example, if a DOM user gets a NodeList object containing the children of an Element, then subsequently adds more children to that element (or removes children, or modifies them), those changes are automatically reflected in the NodeList without further action on the user’s part.

Leave a Reply

Note: Wrap all of your code blocks in <code>...</code> and replace < and > with &lt; and &gt;, respectively.