Skip to main content

Tree Walking

Functions for navigating the DOM hierarchy.

walkChildren

Traverse child elements with depth control.

window.__devtool.walkChildren(selector, depth, filter)

Parameters:

  • selector (string): CSS selector for parent element
  • depth (number, optional): Maximum depth to traverse (default: 3)
  • filter (string, optional): Tag name or CSS selector to filter children

Returns:

{
element: {
tag: "nav",
id: "main-nav",
classes: ["navigation"]
},
children: [
{
element: {tag: "ul", classes: ["nav-list"]},
children: [
{element: {tag: "li", classes: ["nav-item"]}},
{element: {tag: "li", classes: ["nav-item"]}}
]
}
],
childCount: 1,
totalDescendants: 3
}

Examples:

Basic traversal:

window.__devtool.walkChildren('.container', 2)
→ Children up to 2 levels deep

Filter by tag:

window.__devtool.walkChildren('form', 3, 'input')
→ Only input elements within 3 levels

Filter by class:

window.__devtool.walkChildren('.grid', 2, '.card')
→ Only elements with .card class

walkParents

Walk up the DOM tree to the root.

window.__devtool.walkParents(selector)

Parameters:

  • selector (string): CSS selector for starting element

Returns:

[
{
tag: "li",
id: "",
classes: ["menu-item"],
depth: 1
},
{
tag: "ul",
id: "menu",
classes: ["nav-menu"],
depth: 2
},
{
tag: "nav",
id: "main-nav",
classes: [],
depth: 3
},
{
tag: "header",
id: "site-header",
classes: ["sticky"],
depth: 4
},
{
tag: "body",
id: "",
classes: [],
depth: 5
},
{
tag: "html",
id: "",
classes: [],
depth: 6
}
]

Example:

window.__devtool.walkParents('.nested-button')
[{tag: "div", classes: ["button-group"]}, {tag: "form"}, ...]

findAncestor

Find first ancestor matching a condition.

window.__devtool.findAncestor(selector, condition)

Parameters:

  • selector (string): CSS selector for starting element
  • condition (string): CSS selector for the ancestor to find

Returns:

{
found: true,
element: {
tag: "div",
id: "modal-container",
classes: ["modal", "active"],
attributes: {
"data-modal": "confirm",
"role": "dialog"
}
},
depth: 3
}

If not found:

{
found: false,
element: null,
depth: null
}

Examples:

Find form ancestor:

window.__devtool.findAncestor('input', 'form')
{found: true, element: {tag: "form", id: "signup-form"}, depth: 2}

Find by attribute:

window.__devtool.findAncestor('.submit-btn', '[data-section]')
{found: true, element: {tag: "section", attributes: {"data-section": "checkout"}}}

Find by class:

window.__devtool.findAncestor('.item', '.scrollable')
{found: true, element: {tag: "div", classes: ["scrollable", "container"]}}

Common Patterns

Find All Buttons in a Form

const tree = window.__devtool.walkChildren('form#checkout', 5, 'button')
// Returns all button elements within 5 levels

Get Ancestor Chain for Debugging

const parents = window.__devtool.walkParents('.broken-element')
console.log('Element path:', parents.map(p => p.tag + (p.id ? '#' + p.id : '')).join(' > '))
// Output: "div > ul#menu > nav > header#site-header > body > html"

Find Containing Modal

const modal = window.__devtool.findAncestor('.error-message', '[role="dialog"]')
if (modal.found) {
console.log('Error is inside modal:', modal.element.id)
}

Count Nesting Depth

const parents = window.__devtool.walkParents('.deeply-nested')
console.log('Nesting depth:', parents.length)

Find Scroll Container

// Find the scrollable ancestor
const scrollParent = window.__devtool.findAncestor('.list-item', '.scrollable')
if (scrollParent.found) {
const overflow = window.__devtool.getOverflow(scrollParent.element.selector)
console.log('Scroll container:', overflow)
}

Analyze Component Structure

// Walk a component's children to understand structure
const structure = window.__devtool.walkChildren('.data-table', 3)

function printStructure(node, indent = 0) {
console.log(' '.repeat(indent) + node.element.tag +
(node.element.classes.length ? '.' + node.element.classes[0] : ''))
node.children?.forEach(c => printStructure(c, indent + 2))
}

printStructure(structure)
// Output:
// table.data-table
// thead
// tr
// tbody
// tr
// tr

Performance Considerations

  • walkChildren with large depths can be slow on complex DOMs
  • Use specific selectors and filters to limit traversal
  • Consider using depth: 1 for flat structures
  • Filter by tag name (faster) over CSS class (slower)

See Also