首页 > 解决方案 > 检查元素是否重叠的最高效方法

问题描述

我知道你可以通过比较方法中的 top|bottom|right|left 属性来计算一个元素是否与另一个元素重叠getBoundingClientRect。但是,您需要遍历元素才能这样做。我很想知道检查一个元素是否与任何其他元素重叠的高效方法是什么。例如,检查标签一是否覆盖了任何其他元素。然后检查标签二是否与包括标签一在内的任何其他元素重叠而不每次都使用循环,或者这是唯一的方法?

const randomColor = "#" + ((1 << 24) * Math.random() | 0).toString(16);
// dismiss -- just creating less CSS
document.querySelectorAll('.label').forEach((x, i) => {
  document.querySelectorAll('.label')[i].style.background = "#" + ((1 << 24) * Math.random() | 0).toString(16);
});

function overlayCheck() {
  let points = document.querySelectorAll('.label');
  let rightPos = (elem) => elem.getBoundingClientRect().right;
  let leftPos = (elem) => elem.getBoundingClientRect().left;
  let topPos = (elem) => elem.getBoundingClientRect().top;
  let btmPos = (elem) => elem.getBoundingClientRect().bottom;

  for (let i = 1; i < points.length; i++) {
    if (!(
        rightPos(points[i]) < leftPos(points[i - 1]) ||
        leftPos(points[i]) > rightPos(points[i - 1]) ||
        btmPos(points[i]) < topPos(points[i - 1]) ||
        topPos(points[i]) > btmPos(points[i - 1])
      )) {
      points[i].innerHTML = `${points[i].innerHTML} C`;
      console.log(i);
    }
    if (i === points.length - 1) {
      return
    }
  }
}

overlayCheck();
.parent {
  position: relative;
  display: flex;
}

.label {
  height: 75px;
  left: 0;
  width: 100px;
  margin-left: 10px;
  background-color: orange
}

.cover {
  width: 220px;
  position: absolute;
  left: 0;
  height: 50px;
  bottom: 0;
}
<div class="parent">
  <div class="label cover">Label 1</div>
  <div class="label">Label 2</div>
  <div class="label">Label 3</div>
  <div class="label">Label 4</div>
  <div class="label">Label 5</div>
  <div class="label">Label 6</div>
</div>

标签: javascriptecmascript-6

解决方案


我通过反复试验找到了一种方法。我会在这里为任何可以使用它的人发布这个。

// dismiss -- just creating less CSS
const randomColor = "#" + ((1 << 24) * Math.random() | 0).toString(16);
document.querySelectorAll('.label').forEach((x, i) => {
  document.querySelectorAll('.label')[i].style.background = "#" + ((1 << 24) * Math.random() | 0).toString(16);
});

//function to check for overlapping
function overlayCheck() {
  let points = document.querySelectorAll('.label');
  let rightPos = (elem) => elem.getBoundingClientRect().right;
  let leftPos = (elem) => elem.getBoundingClientRect().left;
  let topPos = (elem) => elem.getBoundingClientRect().top;
  let btmPos = (elem) => elem.getBoundingClientRect().bottom;

  for (let i = 0; i < points.length; i++) {
    for (let j = 0; j < points.length; j++) {
      let isOverlapping = !(
        rightPos(points[i]) < leftPos(points[j]) ||
        leftPos(points[i]) > rightPos(points[j]) ||
        btmPos(points[i]) < topPos(points[j]) ||
        topPos(points[i]) > btmPos(points[j])
      );

      if (isOverlapping && j !== i) {
        points[i].innerHTML = `${points[i].innerHTML} C`;
      }
    }
  }
}
overlayCheck();
.parent {
  position: relative;
  display: flex;
}

.label {
  height: 75px;
  left: 0;
  width: 100px;
  margin-left: 10px;
  background-color: orange
}

.cover {
  width: 220px;
  position: absolute;
  left: 0;
  height: 50px;
  bottom: 0;
}
<div class="parent">
  <div class="label cover">Label 1</div>
  <div class="label">Label 2</div>
  <div class="label">Label 3</div>
  <div class="label">Label 4</div>
  <div class="label">Label 5</div>
  <div class="label">Label 6</div>
</div>


推荐阅读