You have two tasks here:
- Detecting element.
- Getting column / row of element.
Detecting element
You can avoid detecting element if you add needed event handler for every grid item.
But if you want to add mouse hover (or other event handler) you can add loop through every grid item and use element.getBoundingClientRect()
method. Demo (I'll add handler for click to avoid polluting console):
var grid = document.querySelector(".grid");
grid.addEventListener("click", function(event) {
var gridItems = this.children;
for (var i = 0; i < gridItems.length; i++) {
var gridItem = gridItems[i];
var rect = gridItem.getBoundingClientRect();
var elementDetected = event.clientX >= rect.left
&& event.clientX <= rect.right
&& event.clientY >= rect.top
&& event.clientY <= rect.bottom;
if (elementDetected) {
console.log(gridItem);
return;
}
}
console.log("no element detected!");
});
.grid {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
grid-gap: 10px;
}
/* styles just for demo */
.grid__item {
background-color: tomato;
color: white;
/* styles for centering text */
display: flex;
align-items: center;
justify-content: center;
}
<div class="grid">
<div class="grid__item">One</div>
<div class="grid__item">Two</div>
<div class="grid__item">Three</div>
<div class="grid__item">Four</div>
<div class="grid__item">Five</div>
<div class="grid__item">Six</div>
<div class="grid__item">Seven</div>
<div class="grid__item">Eight</div>
<div class="grid__item">Nine</div>
</div>
Using jQuery would make this task even simplier due to is(":hover")
method.
$(".grid").click(function(event) {
var hoveredGridItems = $(this).children()
.filter(function() { return $(this).is(":hover"); });
if (hoveredGridItems.length > 0)
console.log(hoveredGridItems[0]);
else
console.log("no element detected!");
});
.grid {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
grid-gap: 10px;
}
/* styles just for demo */
.grid__item {
background-color: tomato;
color: white;
/* styles for centering text */
display: flex;
align-items: center;
justify-content: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="grid">
<div class="grid__item">One</div>
<div class="grid__item">Two</div>
<div class="grid__item">Three</div>
<div class="grid__item">Four</div>
<div class="grid__item">Five</div>
<div class="grid__item">Six</div>
<div class="grid__item">Seven</div>
<div class="grid__item">Eight</div>
<div class="grid__item">Nine</div>
</div>
Getting column / row of element
I would trust only CSS here, so getting column and row would work as expected only when we have explicitly set grid-column
and grid-row
property. So you have lines of code that will work in every case:
// pure JS
var styles = window.getComputedStyle(gritItem);
var gridColumn = styles["grid-column-start"];
var gridRow = styles["grid-row-start"];
// jquery
var gridColumn = $gridItem.css("grid-column");
var gridRow = $griditem.css("grid-row");
If value of gridColumn
and/or gridRow
is not auto / auto
then you know row and column for sure.
But detecting row and column when auto-placement is very unreliable due to different possible column span / row span values, possible margins
of grid items, align-self
and justify-self
(case when element can occupy only part of grid area) etc.