javascript 如何检测元素是否被其他元素覆盖?

189 阅读1分钟

检查元素是否在z轴方向被覆盖

查看知乎 www.zhihu.com/question/42… 博客 www.cnblogs.com/xtreme/p/14…

知识点1: Document.elementFromPoint()

  返回当前文档上处于指定坐标位置最顶层的元素, 坐标是相对于包含该文档的浏览器窗口的左上角为原点来计算的, 通常 x 和 y 坐标都应为正数. 代码不太准确无法判断被透明0覆盖的

知识点2: Document.elementsFromPoint()

  返回当前文档上处于指定坐标位置最顶层的元素数组列表(可进行筛选整合), 坐标是相对于包含该文档的浏览器窗口的左上角为原点来计算的, 通常 x 和 y 坐标都应为正数.

Document.elementFromPoint() 代码无法判断被透明0覆盖的

用知识点2 改进源码如下:

function hasTopOverLayer(element) {
  if (!element) {
    return false;
  }
  const rect = element.getBoundingClientRect(); // 获取目标的矩形信息
  let x = rect.x,
    y = rect.y,
    width = rect.width,
    height = rect.height;

  x |= 0;
  y |= 0;
  width |= 0;
  height |= 0;
  const fintTopElement = (x, y) => {
    return document.elementsFromPoint(x, y).find(el => +window.getComputedStyle(el).opacity > 0);
  };
  // 四顶点取样
  const elements = [
    fintTopElement(x + 1, y + 1),
    fintTopElement(x + width - 1, y + 1),
    fintTopElement(x + 1, y + height - 1),
    fintTopElement(x + width - 1, y + height - 1),
  ];
  const eles = elements.filter(el => !!el);
  // console.log(1111111, elements, rect, element);
  // 判断非本身及非子孙元素
  return eles.some(el => {
    // console.log('some:', el, element, el.contains(element));
    return el === element || el.contains(element);
  });
}