What are the main reasons for creating a recursive function, aside from catering to older browsers like IE6 and 7?
If not, one could opt for using
document.body.querySelectorAll('*')
to target all element nodes within the DOM while disregarding those that are outside of the body element. A sample implementation is provided below:
window.addEventListener('load', function () {
var highlightButton = document.getElementById("highlight");
function search () {
document.body.querySelectorAll('*').forEach(function (el) {
var spanEl = document.createElement('span');
spanEl.innerHTML = el.tagName;
spanEl.className = 'hoverNode';
el.appendChild(spanEl);
});
}
highlightButton.addEventListener('click', search);
});
If so,, here is an alternative approach:
window.addEventListener('load', function () {
var highlightButton = document.getElementById("highlight");
// traverse downwards from rootEl while excluding Comment elements on IE6 7 & 8
function traverseDOMFrom (rootEl, iterator) {
if (!rootEl || rootEl.nodeType !== 1 || typeof iterator !== 'function') {
return;
}
if (rootEl.children && rootEl.children.length > 0) {
Array.prototype.slice.call(rootEl.children).forEach(function (el) {
traverseDOMFrom(el, iterator);
});
}
iterator(rootEl);
}
function search () {
traverseDOMFrom(document.body, function (el) {
var spanEl = document.createElement('span');
spanEl.innerHTML = el.tagName;
spanEl.className = 'hoverNode';
el.appendChild(spanEl);
});
}
highlightButton.addEventListener('click', search);
});
It should be noted that in either case, a polyfill for Array.prototype.forEach()
as well as for EventTarget.addEventListener()
will be required if you wish to support these functionalities on IE6, 7, and 8! Alternatively, achieving similar outcomes can also be done by iterating through the element's array using a custom for loop. As for the .addEventListener
method, a simple .onload event handler could suffice if there is no need for multiple listeners.