1

OK, what I'm trying to do is the following, when I click on any element on the page and I want to build up a tree of the DOM of where the element lives.

example of the html

<html>
  <head>
  </head>
  <body>
    <ul>
     <li><span>Elem 1</span></li>
     <li><span>Elem 2</span></li>
     <li><span>Elem 3</span></li>
    </ul>
  </body>
</html>

This is the JS (comes from an click event and passes through the clicked element)

function getElementIdentifier(elem, domSelector, firstId) {
    if(elem.tagName === 'HTML') {
        return 'HTML ' + domSelector;
    } else {
        return getElementIdentifier(elem.parentNode, ' > ' +elem.tagName + ' ' + domSelector, firstId);
    }
}

which works to an extent but when it comes to the fact that I've clicked on the third item in the list it only retrieves the following:

HTML  > BODY  > UL  > LI  > SPAN

But I want to retrieve the 3rd as this is the one I clicked. I've got a codepen I did to show.

http://codepen.io/tom-maton/pen/FljpL/

I'm not wanting to use jQuery - just looking to use raw js.

Tom Maton
  • 1,564
  • 3
  • 23
  • 41
  • See http://stackoverflow.com/questions/11761881/javascript-dom-find-element-index-in-container – Albert Xing Apr 10 '14 at 20:54
  • I don't see the problem here, your "breadcrumb" is valid for the 3rd element too. – veritas Apr 10 '14 at 20:57
  • As veritas says that is valid, are you meaning you want to get its previous siblings along with the parents? – Patrick Evans Apr 10 '14 at 21:10
  • Its the wrong selector generated, because if I was to pass say the selector into jquery it will only return the first li. Whereas I want to retrieve the HTML > BODY > UL > LI + LI > SPAN for the second and HTML > BODY > UL > LI + LI + LI > SPAN for the 3rd item clicked – Tom Maton Apr 11 '14 at 08:37
  • @TomMaton you want only the previous siblings right? – veritas Apr 14 '14 at 19:13

1 Answers1

2

This is the fastest way to do it (at least for me)

function clickHandler(event) {
    var target = event.target,
    breadcrumb = [];

    while (target) {
        breadcrumb.unshift(target.tagName);
        target = target.parentElement;
    }
    console.log(breadcrumb.join(" > "));
}

document.addEventListener('click', clickHandler, false);

Fiddle here: http://jsfiddle.net/NTEv2/

Version with siblings:

function getTagName(element) {
    return element.tagName;
}
function clickHandler(event) {
    var target = event.target,
        breadcrumb = [],
        temp;

    while (target) {
        target = target.parentElement;
        if (target) {
            breadcrumb.unshift(([].slice.call(target.children).map(getTagName).join(" + ")));
        }
    }

    // HTML is always there
    breadcrumb.unshift(document.documentElement.tagName);

    console.log(breadcrumb.join(" > "));
}

document.addEventListener('click', clickHandler, false);

Fiddle here: http://jsfiddle.net/NTEv2/1/

Version with only previous siblings (as requested):

function clickHandler(event) {
    var target = event.target,
        breadcrumb = [],
        part = [],
        prev = target,
        temp;

    while (target) {
        if (prev) {
            part.unshift(prev.tagName);
            prev = prev.previousElementSibling;
        } else {
            target = target.parentElement;
            prev = target;
            breadcrumb.unshift(part.join(" + "));
            part = [];
        }
    }

    console.log(breadcrumb.join(" > "));
}

document.addEventListener('click', clickHandler, false);

Fiddle here: http://jsfiddle.net/NTEv2/11/

veritas
  • 2,034
  • 1
  • 16
  • 30