How to prevent parentNode madness?

dom, javascript

Solution

As part of my projects, I always write my own toolbox. Sure, I could use jQuery, but I'll stick to my precision toolkit over a sledgehammer, thanks!

With that in mind, have a look at this:

function findParent(source,filter,root) {
    root = root || document.documentElement;
    while(source != root) {
        if( filter(source)) return source;
        source = source.parentNode;
    }
}

In your case, you can now call:

var listId = findParent(
        event.target,
        function(e) {return e.attributes && e.attributes['data-id'];}
    ).getAttribute("data-id");
// note that you should probably break that down, checking if an element
// is found before getting its attribute value... or let the error
// kill your script. Either works.

Now, here it does look a bit more messy than your simple `.parentNode.parentNode`, but it's much more robust because it doesn't rely on depths being a certain number, which I believe is what you were aiming for.

Problem

I have a list of items which diferent event handlers on it. ``` ... <li> <div class="item" data-id="1234"> <h3>Item</h3> <div class="description">...</div> <ul class="lists"> <li data-list-id="1">Add to list A<li> <li data-list-id="2">Add to list B<li> <li data-list-id="3">Add to list C<li> </ul> <button class="delete">delete</button> </div> </li> ... ``` Every `li` under `.list` has a click event registered which looks like this: ``` function addToList(event){ var id = event.target.getAttribute('data-id'); var listId = event.target.parentNode.parentNode.getAttribute('data-id'); // XHR stuff } ``` There is no problem with this code but the `parentNode.parentNode` seems really fragile. For the button would be only one parentNode and for deeper nested elements parentNode^n I guess this is a common problem and there are more robust solutions? With jQuery i would use `$(target).parentNode('.item')` Whats the best way to do this without jQuery?

Original source

Related problems