JSFiddle - React, Tailwind, and code Playground
by darcyclarke
HTML
<div id="test"></div>
<div></div>
<div style="background-color: yellow;"></div>
<span></span>
<span class="box"></span>
<span class="box" data-num="3"></span>
CSS
body * {
display: inline-block;
width: 50px;
height: 50px;
background: red;
}
JavaScript
var els = document.querySelectorAll( 'div, span' );
els = Array.prototype.slice.call( els );
els.forEach( function( el ) {
el.addEventListener( 'click', function( event ) {
console.log( generateUniqeSelector( this ) );
});
});
// Generate Selector By Tag + Attrs
var generateUniqeSelector = function ( el ) {
var index;
var siblings;
var selector = '';
var scopedSelector = '';
var body = document.querySelector( 'body' );
var tagName = el.tagName.toLowerCase();
var parent = el.parentNode;
var attrs = (function( attrs ) {
if ( attrs.length <= 0 ) {
return '';
}
var str = '';
attrs.forEach( function( attr ) {
str += '[' + attr.nodeName + '="' + attr.textContent + '"]';
});
return str;
})( Array.prototype.slice.call( el.attributes ) );
// Return if we have a unique selector
if ( el.id ) {
return '#' + el.id;
}
// Return if we are dealing with body or html elements
if ( tagName === 'html' || tagName === 'body' ) {
return tagName;
}
// Return if tagname + attrs generates unique selector
selector = tagName + attrs;
siblings = document.querySelectorAll( selector );
if ( siblings.length === 1 ) {
return selector;
}
// Return a truly unique selector using a scoped selector and index
index = Array.prototype.indexOf.call( parent.children, el );
while( parent != body ) {
parent = parent.parentNode();
scopedSelector = parent.tagName.toLowerCase() + scopedSelector + ' ';
}
return 'body ' + scopedSelector + '*:nth-child(' + index + ')';
};