0

I need to generate a value of element based on the level in the DOM. e.g. If I have a click event at document level (i.e. listening to any clicks on the pages) and the rendered HTML like this, it needs to traverse through DOM until you see "ID" attribute populated.

<div id="someid">
<div>
    <span>
        <p>
            <a href="javascript:void(0);">
                <span>
                    <strong>Googlie</strong> 
                </span>
            </a>                
        </p>
    </span>
</div>

When I click on "Googlie", it should generate something like this: someid__div_span_p_a_span_strong

Issue:
I do have some code to do this but there is a problem with it. In above, what if I have two elements, right after another as shown below. How do I generate an unique value for strong element? Can I have something without using childNodes location? The childNodes value changes if someone changes the white space between the elements.

...<span>
<strong>Googlie</strong> <br/> <strong>Bingie</strong>
</span>...

    document.onclick = function(obj) {
    var node = obj.target;
    var res = [];
    var etA = "";
    res[0] = false;
    while (!res[0]) {
        res = GetIdFor(node);
        if (!res[0]) {
            var end = node.parentNode.childNodes.length;
            for (var i = 0; i < end; i++) {
                var j = node.parentNode.childNodes[i];
                if (j.nodeType === 1 && j === node) {
                    break;
                }
            }
            etA = "_" + node.tagName + etA;
            node = node.parentNode;
        }
        else {
            etA = res[1] + "_" + etA;
        }
    }
    alert(etA);
};
function GetIdFor(elem) {
    var res = [];
    res[0] = false;
    var d = elem.getAttribute("ID");
    if (d !== "undefined" && d !== null) {
        res[0] = true;
        res[1] = d;
    }
    return res;
}

Now, I know jQuery can help here but that's not THE point. :) Thoughts? Do I not have any other choice but using childNodes level in order to generate this value?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Rachit Patel
  • 209
  • 1
  • 5
  • 14
  • What are you trying to achieve with that id? – Oriol Sep 19 '12 at 18:06
  • Take a look here: http://stackoverflow.com/questions/5728558/jquery-get-the-dom-path-of-the-clicked-a – Hans Then Sep 19 '12 at 18:08
  • @Oriol. The idea is to get that id and be able to reverse engineer and find again in some kind of reporting to show where one clicked. Thx! – Rachit Patel Sep 19 '12 at 19:00
  • @Rac123 Then, if I understand it well, you get the element, you set an id and then you use that id to find the element which has that id (itself). Isn't it a bit nonsense? – Oriol Sep 19 '12 at 23:35

1 Answers1

0

I adapted this answer from Here. The author suggests putting [#] as a sibling number so that you can differentiate between siblings, e.g. someid__div_span_p_a_span_strong[0]

Working jsFiddle Here.

function elementPath(element)
{
    return $(element).parents().andSelf().map(function() {
        var $this = $(this);
        var tagName = this.nodeName;
        if ($this.siblings(tagName).length > 0) {
            tagName += "[" + $this.prevAll(tagName).length + "]";
        }
        return tagName;
    }).get().join(".").toLowerCase();
}

$(document).ready(function() {
    $(document).click(function(e) {
        e.stopPropagation();
        window.alert(elementPath(e.target));
    });
});
Community
  • 1
  • 1
Ed Bayiates
  • 11,060
  • 4
  • 43
  • 62
  • Thanks AresAvatar! After posting I read jQuery selector and found that it always returns ElementType nodes only (value ===1) and not others which makes this easy what I'm after and in fact you answered it in yours. I choose this as an answer but I was more looking into non-jQuery way. I think I actually got it which produces results like this: __#someid__TBODY-1_TR-1_TD-2_DIV-1_DIV-2_A-1 where "-1" are the childNodes position. My idea is to take this and reverse engineer using jQuery. But thanks for your help! – Rachit Patel Sep 19 '12 at 18:50
  • Feel free to post and accept your own answer if you solve it. – Ed Bayiates Sep 19 '12 at 18:51