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?
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));
});
});