I am wondering if there is a way to select a specific element way up the DOM only using vanilla JS while not having to use parentNode
multiple times. I understand you can do this with jQuery and modifying Element.prototype
, but are there any other pretty ways to write this.
const deleteButtons = document.querySelectorAll('.delete-button');
for (var i = 0; i < deleteButtons.length; i++) {
deleteButtons[i].addEventListener('click', (e) => {
e.preventDefault();
//This is the crazy amount of parentNode usage
bookDatabase.child(e.target.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.getAttribute("id")).remove();
});
}
There is really only one other way, which is to use the DOM API element.closest()
, but it does require that you provide a selector that can uniquely identify the particular element you need (or the first element that matches that selector from the descendant's point of view). Without that, multiple uses of the .parent()
method would be required and you'd need to know how many levels up you want to go.
// Starting from the inner most level
var start = document.getElementById("source");
// Let's say you wanted to reference the first ancestor
// that has the "something3" class
start.closest(".something3").classList.add("red");
// Or, the second closest
var firstMatch = start.closest(".something2");
firstMatch.classList.add("yellow");
// Or, even higher
firstMatch.closest(".something1").classList.add("aqua");
// And, of course, you can skip levels
start.closest(".something1").classList.add("dropCap");
#source {background-color:orange; }
.red { background-color:red; }
.yellow { background-color:yellow; font-size:1rem; }
.aqua { background-color:aqua; }
.dropCap { font-size:3em; }
<div class="something1">Level 1
<div class="something2">Level 2
<div class="something3">Level 3
<div id="source">Level 4</div>
</div>
</div>
</div>