-
-
Save jonurry/e36b64f2b6cef858fe921dd83093599a to your computer and use it in GitHub Desktop.
<h1>Heading with a <span>span</span> element.</h1> | |
<p>A paragraph with <span>one</span>, <span>two</span> | |
spans.</p> | |
<script> | |
function byTagName(node, tagName) { | |
let nodes = []; | |
tagName = tagName.toLowerCase(); | |
function addMatchingChildNodes(node) { | |
node.childNodes.forEach(n => { | |
if (n.nodeName.toLowerCase() == tagName) { | |
nodes.push(n); | |
} | |
addMatchingChildNodes(n); | |
}); | |
} | |
addMatchingChildNodes(node); | |
return nodes; | |
} | |
console.log(byTagName(document.body, "h1").length); | |
// → 1 | |
console.log(byTagName(document.body, "span").length); | |
// → 3 | |
let para = document.querySelector("p"); | |
console.log(byTagName(para, "span").length); | |
// → 2 | |
</script> |
Hints
The solution is most easily expressed with a recursive function, similar to the talksAbout
function defined earlier in this chapter.
You could call byTagname
itself recursively, concatenating the resulting arrays to produce the output. Or you can create an inner function that calls itself recursively and that has access to an array binding defined in the outer function, to which it can add the matching elements it finds. Don’t forget to call the inner function once from the outer function to start the process.
The recursive function must check the node type. Here we are interested only in node type 1 (document.ELEMENT_NODE
). For such nodes, we must loop over their children and, for each child, see whether the child matches the query while also doing a recursive call on it to inspect its own children.
14.2 Elements by tag name
The
document.getElementsByTagName
method returns all child elements with a given tag name. Implement your own version of this as a function that takes a node and a string (the tag name) as arguments and returns an array containing all descendant element nodes with the given tag name.To find the tag name of an element, use its
nodeName
property. But note that this will return the tag name in all uppercase. Use thetoLowerCase
ortoUpperCase
string methods to compensate for this.