确定元素是否在另一个元素后面

问题描述 投票:0回答:1

有没有办法确定 elementA 是否在另一个元素“后面”,从而 elementA 对用户不可见?

显然可以使用堆叠上下文,但问题是我们不知道应该查看哪些元素。因此,我们必须迭代 DOM 中的所有元素并对多个元素执行堆叠上下文比较。这在性能方面并不好。

这是一个jsfiddle。那么有没有办法确定 #hidden-element 对用户不可见,因为另一个元素渲染在它上面?

https://jsfiddle.net/b9dek40b/5/

HTML:

<div id="covering-element"></div>
<div>
  <div id="hidden-element"></div>
</div>

款式:

#covering-element {
  position: absolute;
  width: 100px;
  height: 100px;
  background: darksalmon;
  text-align: center;
}

#hidden-element {
  width: 25px;
  height: 25px;
  background: deeppink;
}
javascript browser
1个回答
12
投票

我们的解决方案是使用一些东西来确定元素是否可见并且不在任何其他元素后面。这是我们使用的方法。

  1. window.getCompulatedStyle 检查
    visibility:hidden
    display:none
  2. 来自多个点的
  3. document.elementFromPoint。最常见的情况可能可以通过检查所有角落来处理。尽管我们需要更多的点来获得更稳健的结果。可以使用 Element.getBoundingClientRect()
  4. 轻松检查角坐标

https://jsfiddle.net/k591Lbwu/27/

HTML

<div id="covering-element"></div>
<div>
  <div id="hidden-element"></div>
</div>

<button style="margin-top:100px">Check visibility</button>

CSS

#covering-element {
  position: absolute;
  width: 100px;
  height: 100px;
  background: darksalmon;
  text-align: center;
}

#hidden-element {
  width: 25px;
  height: 25px;
  background: deeppink;
}

JavaScript

document.querySelector('button').addEventListener('click', function() {
    const element = document.getElementById('hidden-element')
  alert('Visible = '+isVisible(element))
})

function isVisible(element) {
  if(!isVisibleByStyles(element)) return false
  if(isBehindOtherElement(element)) return false
  return true
}

function isVisibleByStyles(element) {
    const styles = window.getComputedStyle(element)
  return styles.visibility !== 'hidden' && styles.display !== 'none'
}

function isBehindOtherElement(element) {
  const boundingRect = element.getBoundingClientRect()
  // adjust coordinates to get more accurate results
  const left = boundingRect.left + 1
  const right = boundingRect.right - 1
  const top = boundingRect.top + 1
  const bottom = boundingRect.bottom - 1
  
  if(!element.contains(document.elementFromPoint(left, top))) return true
  if(!element.contains(document.elementFromPoint(right, top))) return true
  if(!element.contains(document.elementFromPoint(left, bottom))) return true
  if(!element.contains(document.elementFromPoint(right, bottom))) return true
  
  return false
}

注意:如果给定元素是节点本身或其后代,则 Node.contains 返回 true。如果您只想检查确切的元素而不是包括它的后代,则应该使用

document.elementFromPoint(...) !== element
作为
isBehindOtherElement

内的条件语句
© www.soinside.com 2019 - 2024. All rights reserved.