2

jQuery: get td elements (or other elements), that are under absolute div (match position)

Let's say i have such html:

<table>
<tr>
  <td>1</td>
  <td>2</td>
</tr>

<tr>
  <td>3</td>
  <td>4</td>
</tr>

<tr>
  <td>5</td>
  <td>6</td>
</tr>
</table>

<div class="abs-hover">
*
</div>

css:

td {
  padding: 8px 20px;
  border: 1px solid #cecece;
}

.abs-hover {
  position: absolute;
  top: 20px;
  left: 30px;
  width: 40px;
  height: 40px;
  background: rgba(140,200,120,0.2);
  border: 2px solid #1cabda;
}

https://jsfiddle.net/L63u02n6/

this absolute container can change it's position on page, but how can i get td, which are under this absolute box?

in first example it's td with text: 1,2,3,4

how can i achieve this? any ideas

brabertaser19
  • 5,678
  • 16
  • 78
  • 184

5 Answers5

1

I wrote a little script that checks if each td is inside the box.

var objTop = $('.abs-hover').offset().top,
  objLeft = $('.abs-hover').offset().left,
  objWidth = $('.abs-hover').width(),
  objHeight = $('.abs-hover').height();

$('table tr td').each(function(e) {
  var self = $(this),
    selfLeft = self.offset().left,
    selfTop = self.offset().top,
    selfWidth = self.width(),
    selfHeight = self.height();
  if ((objLeft + objWidth) > selfLeft && (objLeft < (selfLeft + selfWidth) || objLeft > (selfLeft + selfWidth)) && (objTop + objHeight) > selfTop && objTop < (selfTop + selfHeight)) {
    console.log(self.text() +" is inside")    
  }

});
td {
  padding: 8px 20px;
  border: 1px solid #cecece;
}

.abs-hover {
  position: absolute;
  top: 20px;
  left: 30px;
  width: 40px;
  height: 40px;
  background: rgba(140, 200, 120, 0.2);
  border: 2px solid #1cabda;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr>
    <td>1</td>
    <td>2</td>
  </tr>

  <tr>
    <td>3</td>
    <td>4</td>
  </tr>

  <tr>
    <td>5</td>
    <td>6</td>
  </tr>
</table>

<div class="abs-hover">
  *
</div>
Carsten Løvbo Andersen
  • 26,637
  • 10
  • 47
  • 77
1

You can use Document.elementFromPoint()

The elementFromPoint() method of the Document interface returns the topmost element at the specified coordinates.

var j = $('.abs-hover').position();

elemtopLeft = document.elementFromPoint(j.top, j.left);
elemtopRIght = document.elementFromPoint(j.left + 44, j.top);
elembtmLeft = document.elementFromPoint(j.left, j.top + 44);
elembtmRight = document.elementFromPoint(j.left + 44, j.top + 44);

console.log(elemtopLeft, elemtopRIght, elembtmLeft, elembtmRight)
td {
  padding: 8px 20px;
  border: 1px solid #cecece;
}

.abs-hover {
  position: absolute;
  top: 20px;
  left: 30px;
  width: 40px;
  height: 40px;
  background: rgba(140, 200, 120, 0.2);
  border: 2px solid #1cabda;
}
<script src=https://code.jquery.com/jquery-2.2.4.min.js></script>
<table>
  <tr>
    <td>1</td>
    <td>2</td>
  </tr>

  <tr>
    <td>3</td>
    <td>4</td>
  </tr>

  <tr>
    <td>5</td>
    <td>6</td>
  </tr>
</table>

<div class="abs-hover">
  *
</div>
Abhishek Pandey
  • 13,302
  • 8
  • 38
  • 68
0

You need a collision detection for this, either on ready or after some event.

A good short function for this is given here in this SO-post: https://stackoverflow.com/a/7301852/6248169

Width, height and position on screen to can get with jQuery functions. Then you can run this jquery function here for every TD to compare with your absolute box. If it collides, you set a class on the TD and then afterwards you can select over this class so you have all TDs which are under the DIV.

Hope these words are enough for an idea how to do this and no complete code is needed here.

Martin Wunderlich
  • 153
  • 1
  • 2
  • 6
0

You could also make use of Element.getBoundingClientRect(); function call to get a the positional coordinates of any element. Then go on to compare them with that of the absolute div to find an overlap. It returns an object with attributes - top, right, bottom, left, width. Link to the API

Rajeev Ranjan
  • 3,588
  • 6
  • 28
  • 52
0

Native JS:

function getBounds(el) {
    return {
    left: el.offsetLeft,
    top: el.offsetTop,
    right: el.offsetLeft + el.offsetWidth,
    bottom: el.offsetTop + el.offsetHeight
  };
}

let hoverBounds = getBounds(document.querySelector(".abs-hover"));

document.querySelectorAll("td").forEach((el) => {
  let elBounds = getBounds(el);
  if (
    (
      hoverBounds.left >= elBounds.left && hoverBounds.left <= elBounds.right ||
      hoverBounds.right >= elBounds.left && hoverBounds.right <= elBounds.right
    ) &&
    (
      hoverBounds.top >= elBounds.top && hoverBounds.top <= elBounds.bottom ||
      hoverBounds.bottom >= elBounds.top && hoverBounds.bottom <= elBounds.bottom
    )
  ) {
    console.log(el.innerText, "Yes");
  } else {
    console.log(el.innerText, "No");
  }
});

I suggest use "id" for the hover element. "class" use for several elements.

Vitaly
  • 611
  • 1
  • 7
  • 21