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?
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.
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.
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.
The easiest way to find an HTML element in the DOM, is by using the element id.
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 }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With