Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get CSS path from Dom element

I got this function to get a cssPath :

var cssPath = function (el) {   var path = [];    while (     (el.nodeName.toLowerCase() != 'html') &&      (el = el.parentNode) &&     path.unshift(el.nodeName.toLowerCase() +        (el.id ? '#' + el.id : '') +        (el.className ? '.' + el.className.replace(/\s+/g, ".") : ''))   );   return path.join(" > "); } console.log(cssPath(document.getElementsByTagName('a')[123])); 

But i got something like this :

html > body > div#div-id > div.site > div.clearfix > ul.choices > li

But to be totally right, it should look like this :

html > body > div#div-id > div.site:nth-child(1) > div.clearfix > ul.choices > li:nth-child(5)

Did someone have any idea to implement it simply in javascript ?

like image 358
jney Avatar asked Sep 01 '10 16:09

jney


People also ask

How do I find the CSS path of an element?

If Chrome Dev tools if you select the element in the source pane and right click, then you will see the "Copy CSS Path" option. In newer versions of Chrome, this is (right-click) > Copy > Copy selector .

How do you grab elements from Dom?

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.

How do I identify a DOM element?

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

What is path in Dom?

A so called DOM Path is not definied by the DOM specification itself. The closest thing you can find there, are event paths. An event path is definied as follows: An event has an associated path. A path is a list of structs.


2 Answers

The answer above actually has a bug in it — the while loop breaks prematurely when it encounters a non-element node (e.g. a text node) resulting in an incorrect CSS selector.

Here's an improved version that fixes that problem plus:

  • Stops when it encounters the first ancestor element with an id assigned to it
  • Uses nth-of-type() to make the selectors more readable
     var cssPath = function(el) {         if (!(el instanceof Element))              return;         var path = [];         while (el.nodeType === Node.ELEMENT_NODE) {             var selector = el.nodeName.toLowerCase();             if (el.id) {                 selector += '#' + el.id;                 path.unshift(selector);                 break;             } else {                 var sib = el, nth = 1;                 while (sib = sib.previousElementSibling) {                     if (sib.nodeName.toLowerCase() == selector)                        nth++;                 }                 if (nth != 1)                     selector += ":nth-of-type("+nth+")";             }             path.unshift(selector);             el = el.parentNode;         }         return path.join(" > ");      } 
like image 134
asselin Avatar answered Sep 24 '22 08:09

asselin


To always get the right element, you will need to use :nth-child() or :nth-of-type() for selectors that do not uniquely identify an element. So try this:

var cssPath = function(el) {     if (!(el instanceof Element)) return;     var path = [];     while (el.nodeType === Node.ELEMENT_NODE) {         var selector = el.nodeName.toLowerCase();         if (el.id) {             selector += '#' + el.id;         } else {             var sib = el, nth = 1;             while (sib.nodeType === Node.ELEMENT_NODE && (sib = sib.previousSibling) && nth++);             selector += ":nth-child("+nth+")";         }         path.unshift(selector);         el = el.parentNode;     }     return path.join(" > "); } 

You could add a routine to check for unique elements in their corresponding context (like TITLE, BASE, CAPTION, etc.).

like image 22
Gumbo Avatar answered Sep 25 '22 08:09

Gumbo