Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the DOM path of the clicked <a>

HTML

<body> <div class="lol"> <a class="rightArrow" href="javascriptVoid:(0);" title"Next image"> </div> </body> 

Pseudo Code

$(".rightArrow").click(function() { rightArrowParents = this.dom(); //.dom(); is the pseudo function ... it should show the whole alert(rightArrowParents); }); 

Alert message would be:

body div.lol a.rightArrow

How can I get this with javascript/jquery?

like image 598
Tomkay Avatar asked Apr 20 '11 10:04

Tomkay


People also ask

What is Dom path?

Definition of Document Object Model (DOM) path for an HTML element: DOM path of an element is the position of the element in the HTML code. For example, in Figure 4 the DOM path of the button (DOM button ) is Document. Html. Body. P.

How do I find my DOM element?

The easiest way to access a single element in the DOM is by its unique ID. You can get an element by ID with the getElementById() method of the document object. In the Console, get the element and assign it to the demoId variable. Logging demoId to the console will return our entire HTML element.

What is Dom click?

The HTML DOM click() method simulates a mouse-click on an element. It can be used to click on any element just like a user would do. This is used to fire the elements click event. The click event does event bubbling i.e. it will execute the click event of all its parents too.

How do I access the HTML DOM?

The easiest way to find an HTML element in the DOM, is by using the element id.


2 Answers

Here is a native JS version that returns a jQuery path. I'm also adding IDs for elements if they have them. This would give you the opportunity to do the shortest path if you see an id in the array.

var path = getDomPath(element); console.log(path.join(' > ')); 

Outputs

body > section:eq(0) > div:eq(3) > section#content > section#firehose > div#firehoselist > article#firehose-46813651 > header > h2 > span#title-46813651 

Here is the function.

function getDomPath(el) {   var stack = [];   while ( el.parentNode != null ) {     console.log(el.nodeName);     var sibCount = 0;     var sibIndex = 0;     for ( var i = 0; i < el.parentNode.childNodes.length; i++ ) {       var sib = el.parentNode.childNodes[i];       if ( sib.nodeName == el.nodeName ) {         if ( sib === el ) {           sibIndex = sibCount;         }         sibCount++;       }     }     if ( el.hasAttribute('id') && el.id != '' ) {       stack.unshift(el.nodeName.toLowerCase() + '#' + el.id);     } else if ( sibCount > 1 ) {       stack.unshift(el.nodeName.toLowerCase() + ':eq(' + sibIndex + ')');     } else {       stack.unshift(el.nodeName.toLowerCase());     }     el = el.parentNode;   }    return stack.slice(1); // removes the html element } 
like image 129
Michael Connor Avatar answered Oct 03 '22 23:10

Michael Connor


Using jQuery, like this (followed by a solution that doesn't use jQuery except for the event; lots fewer function calls, if that's important):

$(".rightArrow").click(function() {   var rightArrowParents = [];   $(this).parents().addBack().not('html').each(function() {     var entry = this.tagName.toLowerCase();     if (this.className) {       entry += "." + this.className.replace(/ /g, '.');     }     rightArrowParents.push(entry);   });   alert(rightArrowParents.join(" "));   return false; }); 

Live example:

$(".rightArrow").click(function() {    var rightArrowParents = [];    $(this).parents().addBack().not('html').each(function() {      var entry = this.tagName.toLowerCase();      if (this.className) {        entry += "." + this.className.replace(/ /g, '.');      }      rightArrowParents.push(entry);    });    alert(rightArrowParents.join(" "));    return false;  });
<div class="lol multi">    <a href="#" class="rightArrow" title="Next image">Click here</a>  </div>  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

(In the live examples, I've updated the class attribute on the div to be lol multi to demonstrate handling multiple classes.)

That uses parents to get the ancestors of the element that was clicked, removes the html element from that via not (since you started at body), then loops through creating entries for each parent and pushing them on an array. Then we use addBack to add the a back into the set, which also changes the order of the set to what you wanted (parents is special, it gives you the parents in the reverse of the order you wanted, but then addBAck puts it back in DOM order). Then it uses Array#join to create the space-delimited string.

When creating the entry, if there's anything on className we replace spaces with . to support elements that have more than one class (<p class='foo bar'> has className = "foo bar", so that entry ends up being p.foo.bar).

Just for completeness, this is one of those places where jQuery may be overkill, you can readily do this just by walking up the DOM:

$(".rightArrow").click(function() {   var rightArrowParents = [],     elm,     entry;    for (elm = this; elm; elm = elm.parentNode) {     entry = elm.tagName.toLowerCase();     if (entry === "html") {       break;     }     if (elm.className) {       entry += "." + elm.className.replace(/ /g, '.');     }     rightArrowParents.push(entry);   }   rightArrowParents.reverse();   alert(rightArrowParents.join(" "));   return false; }); 

Live example:

$(".rightArrow").click(function() {    var rightArrowParents = [],      elm,      entry;      for (elm = this; elm; elm = elm.parentNode) {      entry = elm.tagName.toLowerCase();      if (entry === "html") {        break;      }      if (elm.className) {        entry += "." + elm.className.replace(/ /g, '.');      }      rightArrowParents.push(entry);    }    rightArrowParents.reverse();    alert(rightArrowParents.join(" "));    return false;  });
<div class="lol multi">    <a href="#" class="rightArrow" title="Next image">Click here</a>  </div>  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

There we just use the standard parentNode property of the element repeatedly to walk up the tree until either we run out of parents or we see the html element. Then we reverse our array (since it's backward to the output you wanted), and join it, and we're good to go.

like image 27
T.J. Crowder Avatar answered Oct 04 '22 00:10

T.J. Crowder