【问题标题】:Check which element is above other检查哪个元素高于其他元素
【发布时间】:2019-07-16 18:40:21
【问题描述】:

假设我有两个重叠的框 (fiddle)

<html>
<body>
    <div class="box">element 1</div>
    <div class="box" style="left: 20px; top: 10px; background-color: red;">element 2</div>
    <style>
      .box {
        background-color: green;
        position: absolute;
        width: 100px;
        height: 100px;
        border: 1px sold red;
      }
    </style>
</body>
</html>

有没有办法在 vanilla javascript 中判断哪个框在另一个之上?我只关心用户在上面的视觉感知。

类似下面的东西

isAbove(el1, el2) // false
isAbove(el2, el1) // true

【问题讨论】:

  • 以上是什么意思? z-index 更高?
  • @epascarello 这意味着在视觉上高于另一个。问题是如何检查。通过 z-index 进行检查在上面的示例中不起作用。
  • 我知道,您的问题不清楚,因此为什么它在过去 6 小时内没有引起注意。删除的答案认为它意味着x,y位置。
  • 从概念上讲,您需要找到他们的第一个共同的父母,然后通过声明确定哪个先出现
  • 注意,heght 应该是 height 在 CSS 的问题和链接 jsfiddle

标签: javascript overlapping


【解决方案1】:

只需获取这些元素 zIndex 并比较它们

【讨论】:

    【解决方案2】:

    关于我能想到的唯一方法是获取所涉及元素的 dom 路径并通过声明检查哪个先出现;这应该让您在没有 z-index 的情况下知道哪个元素自然会显示在另一个元素的“顶部”。

    function getAncestors(ele) {
      var ancestors = [ele];
      while(ele.parentElement) { // walk all parents and get ancestor list
        ele = ele.parentElement;
        ancestors.push(ele);
      }
      return ancestors.reverse(); // flip list so it starts with root
    }
    
    function declaredBefore(ele1,ele2) {
      var a1 = getAncestors(ele1);
      var a2 = getAncestors(ele2);
      for(var i=0;i<a1.length;i++) { // check path, starting from root
         if(a1[i] !== a2[i]) { // at first divergent path
            var testNodes = a1[i-1].childNodes; // get children of common ancestor
            for(var j=0;j<testNodes.length;j++) { // check them for first disparate ancestor
                if(testNodes[j] === a1[i]) { return true; } // ele1 is first
                if(testNodes[j] === a2[i]) { return false; } // ele2 is first
            }
         }
      }
      return undefined; // could not determine who was first
    }
    
    function isAbove(ele1, ele2) {
      // rudimentary z-index check for eles sharing a parent 
      if(ele1.parentNode === ele2.parentNode) {
        var z1 = ele1.style.zIndex;
        var z2 = ele2.style.zIndex;
        if(z1 !== undefined && z2 !== undefined) { // if both have z-index, test that
          return z1 > z2;
        }
      }
      return declaredBefore(ele2, ele1); // if 2 is declared before 1, 1 is on top
    }
    

    这个解决方案远非万无一失,但它至少应该让你知道哪个元素是最后声明的,考虑到 dom 树的层次结构。除非元素共享父元素,否则它也不比较 zIndex,尽管您也可以修改它以检查父元素的 zIndex 层次结构。

    【讨论】:

    • 这假设虽然一个元素跟随另一个元素,但首先呈现。这是所有浏览器的行为方式吗?
    • 文档顺序中最后出现的内容都呈现在顶部;在没有 z-index 的情况下,元素根据它们的文档树位置按 z 顺序排列,尊重层次结构。您可以使用 css 解决此问题(flexbox 是一个很好的示例,您可以更改可能会更改内部 z 顺序的项目顺序)。我的示例测试声明为 last 的那个,默认情况下,它在渲染方面应该是“在顶部”。
    猜你喜欢
    • 2011-12-06
    • 1970-01-01
    • 1970-01-01
    • 2013-09-17
    • 1970-01-01
    • 2012-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多