Skip to content

Instantly share code, notes, and snippets.

@ErosLever
Last active December 13, 2024 20:49
Show Gist options
  • Save ErosLever/51c794dc1f2bab888f571e47275c85cd to your computer and use it in GitHub Desktop.
Save ErosLever/51c794dc1f2bab888f571e47275c85cd to your computer and use it in GitHub Desktop.
JS GetCssSelector function - Handy function to get the full CSS selector of any element in the page
// you can include this from: https://cdn.rawgit.com/ErosLever/51c794dc1f2bab888f571e47275c85cd/raw/get-css-selector.js
/**
* Handy function to get the full CSS selector of any element in a web page
* @param {Element} e - the Element whose selector will be returned
* @returns {string} s - the complete CSS Selector including all ancestors elements
*/
function getFullSelector(e){
var s = "", t, i, c, p, n;
do{
t = e.tagName.toLowerCase();
i = e.hasAttribute("id") ? "#" + e.id : "";
c = e.hasAttribute("class") ? "." + e.className.split(/\s+/).join(".") : "";
p = e.parentNode;
n = Array.prototype.filter.call(e.parentNode.childNodes,function(x){
return x.nodeType == Node.ELEMENT_NODE;
}).indexOf(e) + 1;
s = t + i + c + ":nth-child(" + n + ") > " + s;
}while( !p || !(e = p).tagName.match(/^HTML$/i) );
return s.slice(0,-3);
}
/**
* Handy function to get the minimal CSS selector of any element in a web page
* @param {Element} e - the Element whose selector will be returned
* @returns {string} s - the minimal CSS Selector including its ancestors elements
*/
function getMinSelector(e){
var s = "", t, i, c, p, n;
do{
t = e.tagName.toLowerCase();
i = e.hasAttribute("id") ? "#" + e.id : "";
c = e.hasAttribute("class") ? "." + e.className.trim().split(/\s+/).map(x=>x.replace(/([^\w\-\_])/g,'\\$1')).join(".") : "";
p = e.parentNode;
n = Array.prototype.filter.call(e.parentNode.childNodes,function(x){
return x.nodeType == Node.ELEMENT_NODE;
}).indexOf(e) + 1;
n = ":nth-child(" + n + ")";
if(i && p.querySelectorAll(i).length == 1)
s = i + " > " + s;
else if(p.querySelectorAll(t).length == 1)
s = t + " > " + s;
else if(c && p.querySelectorAll(t+c).length == 1)
s = t + c + " > " + s;
else if(i && c && p.querySelectorAll(t+i+c).length == 1)
s = t + i + c + " > " + s;
else
s = t + i + c + n + " > " + s;
}while( !p || !(e = p).tagName.match(/^HTML$/i) );
// try to remove parent selectors
cs = s.slice(0,-(" > ".length)).split(" > ");
s = cs.pop();
while( document.querySelectorAll(s).length > 1 ){
s = cs.pop() + " > " + s;
}
return s;
}
document.addEventListener('click', function(e) {
e = e || window.event;
var target = e.target || e.srcElement;
console.log( getFullSelector( target ) );
console.log( getMinSelector( target ) );
}, false);
@yarcowang
Copy link

Hello, friend, getMinSelector seems doesn't work for me.

Uncaught DOMException: Failed to execute 'querySelectorAll' on 'Element': 'div.say.relative.bg-[#5ee5de].mb-4.mr-3.rounded-l.p-1.5.text-black' is not a valid selector.

@ErosLever
Copy link
Author

ErosLever commented Sep 30, 2024

I gave it a quick look and found an issue here: e.className.split(/\s+/) when the className contains extra spaces (e.g., at the end). I fixed this adding .trim() to get rid of extra spaces.

Give it a try with the updated code. Keep in mind this is old code I wrote back in 2016, thus not really maintained.

@ErosLever
Copy link
Author

Double checked your error, you have invalid CSS characters in your class names: bg-[#5ee5de] should not be a valid CSS class name. Although some browsers still accept it. document.querySelector requires these special character to be escaped (with a \\).
I added .replace(/([^\w\-\_])/g,'\\$1') to escape any non-alphanumeric, hyphen or underscore char.

@yarcowang
Copy link

@ErosLever Oh, sorry. Github didn't add such a timestamp (except I explicitly visit "Revisions" tab), I didn't notice that.
bg-[#5ee5de] that thing comes from tailwindcss.
Thank you for that though.

@antonmedv
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment