CUTCODEDOWN
Minimalist Semantic Markup

Welcome Guest
Please Login or Register

If you have registered but not recieved your activation e-mail in a reasonable amount of time, please use our Contact Form for assistance. Include both your username and the e-mail you tried to register with.

Author Topic: JavaScript: Walking the DOM  (Read 381 times)

Jason Knight

  • Administrator
  • Sr. Member
  • *****
  • Posts: 405
  • Karma: +62/-1
    • CutCodeDown -- Minimalist Semantic Markup
JavaScript: Walking the DOM
« on: 24 Oct 2019, 03:56:13 pm »
I'm often surprised how many people don't grasp the concepts of "node walking". For example, let's say you already had a hook to a parent UL.

HTML
Code: [Select]
<ul id="stuff">
<li>Value 1</li>
<li>Value 2</li>
<li>Value 3</li>
</ul>

JS
Code: [Select]
var stuff = document.getElementById('stuff');

If you wanted to go through all of it's immediate child elements, most people would either do stuff.getElementsByTagName or document.querySelectorAll('#stuff > li') and then loop through the result.

What if I told you there's a faster executing way of doing this.

JS
Code: [Select]
var li = stuff.firstElementChild;
if (li) do {
  // whatever you want to do with the LI
} while (li = li.nextElementSibling);

The getElementsByTagName and querySelectorAll routines are slow, they often build new node lists that the JavaScript engine has to maintain, clean up after, etc, etc.

By simply walking through the DOM elements children, starting at the first and looking for the next sibling until there are none, we can bypass all that using element references that already exist on the DOM.

This is the heart of "walking the DOM".

If you're willing to risk recursive calls, this can be written into a simple callback function to walk ALL children of the element.

JS
Code: [Select]
function walk(e, callback) {
if (e) do {
callback(e);
if (e.firstElementChild) walk(e.firstElementChild, callback);
} while (e = e.nextElementSibling);
} // walk

Whilst recursion is often frowned upon, if your HTML nests deep enough for the stack to pop its top, there's something horrifyingly wrong with your HTML!

You can also use the normal Node.firstChild / Node.nextSibling methods in there, just beware that textNodes,

... and of course keep in mind that IE8/earlier has no clue what firstElementSibling / lastElementSibling / nextElementChild / previousElementChild are, so you have to use the non-element equivalents and then test for Node.nodetype == 1; The non-element approach can be really handy though if you want to compact the text content of an element in situations where the browser implementation differences of Element.textContent (or worse, legacy IE's innerText) gets in the way.

Walking the DOM is a very powerful technique for going through a page, it really should be used more than it is.

In Soviet Russia, the DOM walks you...
Sorrow hides well in your shell. A fellow man with hurt to spare.
Dear one, here I am to share the fear. An act of kindness, without an amen.
Come in, the fire's warm. Burn the rope and dance some more.

Jason Knight

  • Administrator
  • Sr. Member
  • *****
  • Posts: 405
  • Karma: +62/-1
    • CutCodeDown -- Minimalist Semantic Markup
Re: JavaScript: Walking the DOM
« Reply #1 on: 4 Mar 2020, 09:10:29 am »
Nevermind, new code doesn't actually work.
« Last Edit: 4 Mar 2020, 12:06:44 pm by Jason Knight »
Sorrow hides well in your shell. A fellow man with hurt to spare.
Dear one, here I am to share the fear. An act of kindness, without an amen.
Come in, the fire's warm. Burn the rope and dance some more.

jmrker

  • Junior Member
  • *
  • Posts: 32
  • Karma: +1/-0
Re: JavaScript: Walking the DOM
« Reply #2 on: 4 Mar 2020, 08:16:13 pm »
Can you expand upon the statement: "new code doesn't actually work."?

Since it is always new to me, which is the "new code" part?
It is the whole post or just the recursive part?

Jason Knight

  • Administrator
  • Sr. Member
  • *****
  • Posts: 405
  • Karma: +62/-1
    • CutCodeDown -- Minimalist Semantic Markup
Re: JavaScript: Walking the DOM
« Reply #3 on: 5 Mar 2020, 01:42:19 am »
Can you expand upon the statement: "new code doesn't actually work."?

Sorry there, I posted a new version that didn't rely on recursion, but it didn't fly because you need an extra loop to go to the parentNode.nextSlbling || parentNode.parentNode || parentNode.nextSlbling || parentNode.parentNode ||etc, etc, etc, forevery.

The versions in the first post work as listed.
Sorrow hides well in your shell. A fellow man with hurt to spare.
Dear one, here I am to share the fear. An act of kindness, without an amen.
Come in, the fire's warm. Burn the rope and dance some more.

jmrker

  • Junior Member
  • *
  • Posts: 32
  • Karma: +1/-0
Re: JavaScript: Walking the DOM
« Reply #4 on: 5 Mar 2020, 11:26:40 pm »
OK, so post #2 originally contained some code that you deleted from the post #2.
That now makes more sense to me. 
I had run the code from the post #1 and thought I understood it, so the "doesn't work" statement confused me.

 

Advertisement