0

Through JavaScript, I want to find out how to find whether a span and a button are touching. I saw something, Element.getBoundingClientRect(). If that is the way to do it, how do I properly do it?

I've already attempted to use Element.getBoundingClientRect() but most likely not used it properly.

  var span1 = document.getElementById("mySpan")
  var button = document.getElementById("myButton")
  if(touches(span1, button)){
   ...
   }
Squill.is.me
  • 73
  • 11

4 Answers4

1

Checks if (inline elements) a span element and button element are next to each other.

var span = document.getElementsByTagName("span")[0]
var btn = document.getElementsByTagName("button")[0]

if(touches(span, btn)){
  console.log('touching!')
}

function touches(span, btn) {
   var rect1 = span.getBoundingClientRect();
   var rect2 = btn.getBoundingClientRect();

  if (rect1.right == rect2.left) {
     return true;
  }
}
<span>Span</span><button>Btn</button>

As for block elements such as div elements

var div1 = document.getElementsByTagName("div")[0]
var div2 = document.getElementsByTagName("div")[1]

if(touches(div1, div2)){
  console.log('Touching!')
}

function touches(div1, div2) {
  var rect1 = div1.getBoundingClientRect();
  var rect2 = div2.getBoundingClientRect();

  if (rect1.bottom == rect2.top) {
      return true;
  }
}
<div>Div 1</div><div>Div 2</div>
Khalid Ali
  • 1,224
  • 1
  • 8
  • 12
  • It works, but unfortunately it gave me another bug with the (for lack of better word) hitboxes of elements. Thank you! – Squill.is.me Apr 23 '19 at 01:49
1

As specified in the second response to this question, with pure Javascript, getBoundingClientRect() is a correct approach.

Take a look at the code below, this should do the work:

function touches(a, b) {
  var aRect = a.getBoundingClientRect();
  var bRect = b.getBoundingClientRect();

  return !(
      ((aRect.top + aRect.height) < (bRect.top)) ||
      (aRect.top > (bRect.top + bRect.height)) ||
      ((aRect.left + aRect.width) < bRect.left) ||
      (aRect.left > (bRect.left + bRect.width))
  );
}
piraces
  • 1,320
  • 2
  • 18
  • 42
0

getBoundingClientRect is what you want.

The code below is a simple example. You may need to add additional logic.

var span1 = document.getElementById("mySpan")
var button = document.getElementById("myButton")
var clickMe = document.getElementById("clickMe")
var outer = document.getElementById("outer")

function touches(el1, el2) {
  const r1 = el1.getBoundingClientRect();
  const r2 = el2.getBoundingClientRect();
  
  console.log(r1.right, r2.left);
  
  if (r2.left - r1.right < 1) {
    console.log('touching');
  }
  else {
    console.log('not touching');
  }
}

touches(span1, button);

clickMe.addEventListener('click', () => {
  outer.classList.toggle('touch');
  setTimeout(() => {
    touches(span1, button);
  },0);
});
.outer {
  font: 14px Tahoma;
  position: relative;
}

#mySpan {
  background-color: red;
}

.touch #myButton {
  margin-left: -4px;
}
<div id="outer">
  <span id="mySpan">span</span>
  <button id="myButton">Button</button>
  <hr/>
  <button id="clickMe">Click Me</button>
</div>
Intervalia
  • 10,248
  • 2
  • 30
  • 60
0

Start by getting the client rect of the two elements:

var span1 = document.getElementById("mySpan");
var button = document.getElementById("myButton");

var rect1 = span1.getBoundingClientRect();
var rect2 = button.getBoundingClientRect();

var overlap = (rect1.right == rect2.left ||  // right to left touching
rect1.left == rect2.right ||                 // left to right touching
rect1.bottom == rect2.top ||                 // bottom to top touching
rect1.top == rect2.bottom)                   // top to bottom touching

if(overlap){
  // ... do your stuff
}

if one or more expressions in the parenthese are true, there's touching. If all are false, there must be an overlapping or not touching.

How to check if an element is overlapping other elements?

adapted from there...

bloo
  • 1,416
  • 2
  • 13
  • 19