Рекурсия есть:
const getElementsWithDepth = (el, depth = 0) =>
[...el.children].reduce((acc, n) => (
acc.push(...getElementsWithDepth(n, depth + 1)),
acc
), [ { el, depth } ]);
Рекурсии нет:
function getElementsWithDepth(root) {
const result = [];
for (const stack = [ [ root, 0 ] ]; stack.length;) {
const [ el, depth ] = stack.pop();
result.push({ el, depth });
stack.push(...Array.from(el.children, n => [ n, -~depth ]).reverse());
}
return result;
}
// или
const getElementsWithDepth = root =>
Array.prototype.reduce.call(
root.querySelectorAll('*'),
(acc, n) => {
acc.push({ el: n, depth: 1 });
for (; (n = n.parentNode) !== root; acc[acc.length - 1].depth++) ;
return acc;
},
[ { el: root, depth: 0 } ]
);