最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Can javascript tell if element is on top other element? - Stack Overflow

programmeradmin0浏览0评论

Can javascript tell if element is on top other element?

Consider this markup:

<!doctype html>
<html>
<style>
section div {width: 100px; position: absolute; border: 1px solid black; }
</style>
<body>
    <section>
        <div id="div1" style="height: 400px; background: blue;"></div>
        <div id="div2" style="height: 300px; background: red;"></div>
        <div id="div3" style="height: 200px; background: yellow;"></div>
        <div id="div4" style="height: 100px; background: green;"></div>
    </section>
</body>
</html>

How can I know (for example) if there is something under div3?

Can javascript tell if element is on top other element?

Consider this markup:

<!doctype html>
<html>
<style>
section div {width: 100px; position: absolute; border: 1px solid black; }
</style>
<body>
    <section>
        <div id="div1" style="height: 400px; background: blue;"></div>
        <div id="div2" style="height: 300px; background: red;"></div>
        <div id="div3" style="height: 200px; background: yellow;"></div>
        <div id="div4" style="height: 100px; background: green;"></div>
    </section>
</body>
</html>

How can I know (for example) if there is something under div3?

Share Improve this question asked Feb 20, 2019 at 22:41 A. MeshuA. Meshu 4,1482 gold badges23 silver badges35 bronze badges 10
  • Do you want just a collision detection (something is touching div3), or checking all elements for positions? – Jack Bashford Commented Feb 20, 2019 at 22:45
  • 1 @JackBashford yes but just inside this particular section and just for divs. – A. Meshu Commented Feb 20, 2019 at 22:48
  • When you say under, are you referring to it being a sibling element ,or under, as in div3 is visually obscuring some other element? – Evan Trimboli Commented Feb 20, 2019 at 22:54
  • 1 @kanhaishah this is exactly what i am reading right now. – A. Meshu Commented Feb 20, 2019 at 23:02
  • 1 @RickHitchcock actually div4 is on top all other 3. – A. Meshu Commented Feb 20, 2019 at 23:10
 |  Show 5 more ments

4 Answers 4

Reset to default 3

The code below will return true if something is underneath a div. In your example, it returns true for all divs except div1, because its height is larger than the others.

const isOnTop = (id) => {
  let element = document.querySelector(id),
      divs = document.querySelectorAll('section div');

  return [...divs].some(div =>
    div.getBoundingClientRect().bottom > element.getBoundingClientRect().bottom
  );
}

const isOnTop = (id) => {
  let element = document.querySelector(id),
      divs = document.querySelectorAll('section div');

  return [...divs].some(div =>
    div.getBoundingClientRect().bottom > element.getBoundingClientRect().bottom
  );
}

console.log(isOnTop('#div1'));  // false
console.log(isOnTop('#div2'));  // true
console.log(isOnTop('#div3'));  // true
console.log(isOnTop('#div4'));  // true
section div {
  width: 100px;
  position: absolute;
  border: 1px solid black;
}
<section>
  <div id="div1" style="height: 400px; background: blue;"></div>
  <div id="div2" style="height: 300px; background: red;"></div>
  <div id="div3" style="height: 200px; background: yellow;"></div>
  <div id="div4" style="height: 100px; background: green;"></div>
</section>

Here is the code which I think should work (it is a pseudo code)

var div3_position = document.getElementById('div3').getBoundingClientRect();
var divs = document.getElementsByTagName("div");
var inner_div_pos = null;
var div3_zindex = getStyle('div3', "zIndex");
var zInd = null;
for (var i = 0; i < divs.length; i++) {
    if (divs[i].id !== 'div3') {
        inner_div_pos = divs[i].getBoundingClientRect();
        zInd = getStyle(divs[i].id, "zIndex");
        if (!doesPointCollide(inner_div_pos) && zInd < div3_zindex) {
            console.log('element is under');
        }
    }
}

function doesPointCollide(p) {
    return !(p.x < div3_position.left || p.x > div3_position.right || p.y >
        div3_position.bottom || p.y < div3_position.top)
}

function getStyle(el, styleProp) {
    var x = document.getElementById(el);

    if (window.getComputedStyle) {
        var y = document.defaultView.getComputedStyle(x, null).getPropertyValue(styleProp);
    } else if (x.currentStyle) {
        var y = x.currentStyle[styleProp];
    }

    return y;
}

Okay, I didn't understand the behavior... beyond the correct answer, if someone wants to know if two elements overlap...

function overLaps(el1, el2) {
  const a = el1.getBoundingClientRect();
  const b = el1.getBoundingClientRect();

  if (a.top < b.top && a.bottom > b.top) return true;
  if (a.top < b.bottom && a.bottom > b.bottom) return true;
  if (a.left < b.left && a.left > b.left) return true;
  if (a.left < b.right && a.left > b.right) return true;

  return false;
}

Original Answer:

You'll need to check the elements from the parent/tree for zIndex, offset position and order. It will require a bit of recursion and depending on the depth may bit a bit cumbersome. If you are controlling the rendering/adjustments, it may be easier to do collision detection with your data model/controller.

Improving on @Tracker1 's response,

// Checks if two elements collide
const elementsColliding = function (el1, el2) {
    const a = el1.getBoundingClientRect()
    const b = el2.getBoundingClientRect()
    
    if (
        ((a.top < b.top) && ((a.top+a.height) > b.top)) ||
        ((a.bottom < b.bottom) && ((a.bottom+a.height) > b.bottom)) ||
        ((a.left < b.left) && ((a.left+a.width) > b.left)) ||
        ((a.right < b.right) && ((a.right+a.width) > b.right))
    ) {
        return true
    }

    return false
}

This checks if two elements collide any way. Not sure why original answer wasn't working for me.. But a.left < b.left && a.left > b.left isn't really doing nothing because it's an impossible statement. Also, the previous answer isn't checking if the elements touch partially (e.g el1 x-axis: 60 to 80, el2 y-axis 79 to 100)

发布评论

评论列表(0)

  1. 暂无评论