Reputation: 615
I created a simple event listener for clicks:
window.addEventListener("click", function (event) {
console.log(event);
});
From what I see, the event object contains a lot of useful data about the parent elements, HTML and CSS data of the clicked element.
Is there a way to build a CSS-selector (hopefully unique) from these event objects? If yes, are there any open-source solutions you can think of?
Upvotes: 1
Views: 1731
Reputation: 1074168
Yes, it's entirely possible to build a unique CSS selector for any element in the DOM, because of the pseudo-class :nth-child
which lets us differentiate between two elements with the same characteristics in the same parent.
Here's a simple example, which builds a selector using the tag name and its position relative to other elements within its parent. This example builds and shows the selector, then uses it a quarter second later to add a 'clicked' class to the element (which shows it in bold green):
// Find the index of the given element in its parent
function indexOf(element) {
var parent = element.parentNode;
var child, index = 1;
for (child = parent.firstElementChild;
child;
child = child.nextElementSibling) {
if (child === element) {
return index;
}
++index;
}
return -1;
}
document.addEventListener("click", function(e) {
// Starting from this element, build a tagname:nth-child(x) selector
// for it, then prepend one for each of its parents up to BODY
var element = e.target;
var selector = element.tagName + ":nth-child(" + indexOf(element) + ")";
while ((element = element.parentElement) != null) {
if (element.tagName === "BODY") {
selector = "BODY > " + selector;
break;
}
selector = element.tagName + ":nth-child(" + indexOf(element) + ") > " + selector;
}
show(selector);
});
function show(selector) {
console.log(selector);
setTimeout(function() {
document.querySelector(selector).classList.add("clicked");
}, 250);
}
#container, #container div {
border: 1px solid #ddd;
}
.clicked {
color: green;
font-weight: bold;
}
<div id="container">
<div>
<span>one</span>
<span>two</span>
<span>three</span>
<span>four</span>
</div>
<div>
<span>one</span>
<span>two</span>
<span>three</span>
<span>four</span>
</div>
</div>
Upvotes: 3