I want to retrieve a specific attribute value from inside nested child nodes. what is the best way to do this?
Below code works, but I will not know the number of child nodes every time.
parent.childNodes[0].childNodes[0].childNodes[0].getAttribute('placeholder');
You can solve this with a recursive function.
I made this one for solving the issue.
function getNestedAttribute(node, attrib) {
// this is not really eficient but I forced it to use childnodes
if (node.childNodes.length && node.children.length) {
node.childNodes.forEach((child) => {
if (child.nodeName === "#text") return;
return getNestedAttribute(child, attrib);
});
}
else {
let attr = node.getAttribute(attrib) || null;
if (!attr) return;
console.log(`[${attrib}]`, attr, {
info: {
node,
attrib,
},
});
}
}
And here you have a working solution=)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Recursive Placeholder</title>
</head>
<body>
<ul id="parent">
<li>
<ul>
<li><input type="text" placeholder="hi there" /></li>
<li><input type="text" placeholder="hola" /></li>
</ul>
</li>
</ul>
<button type="button" onclick="getPlaceholder()">Get Placeholder</button>
<div>
<div>
<div>
<div>
<button type="button" onclick="getAllTypes()">Get Types</button>
</div>
</div>
</div>
</div>
<script>
function getPlaceholder() {
const parent = document.getElementById("parent");
getNestedAttribute(parent, "placeholder");
}
function getNestedAttribute(node, attrib) {
if (node.childNodes.length && node.children.length) {
node.childNodes.forEach((child) => {
if (child.nodeName === "#text") return;
return getNestedAttribute(child, attrib);
});
} else {
let attr = node.getAttribute(attrib) || null;
if (!attr) return;
console.log(`[${attrib}]`, attr, {
info: {
node,
attrib,
},
});
}
}
// Extra:
function getAllTypes() {
getNestedAttribute(document.body, "type");
}
</script>
</body>
</html>