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

javascript - Determine if element is behind another - Stack Overflow

programmeradmin3浏览0评论

Is there a way to determine whether elementA is "behind" another element and thus elementA would not be visible to the user?

Obviously it's possible to do with stacking context, but the thing is that we do not know which elements we should be looking at. Therefore we would have to iterate through all the elements in DOM and perform stacking context parison for multiple elements. That is not good in terms of performance.

Here's a jsfiddle. So is there a way to determine that #hidden-element is not visible to the user, because another element is rendered on top of it?

/

HTML:

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

Styles:

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

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

Is there a way to determine whether elementA is "behind" another element and thus elementA would not be visible to the user?

Obviously it's possible to do with stacking context, but the thing is that we do not know which elements we should be looking at. Therefore we would have to iterate through all the elements in DOM and perform stacking context parison for multiple elements. That is not good in terms of performance.

Here's a jsfiddle. So is there a way to determine that #hidden-element is not visible to the user, because another element is rendered on top of it?

https://jsfiddle/b9dek40b/5/

HTML:

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

Styles:

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

#hidden-element {
  width: 25px;
  height: 25px;
  background: deeppink;
}
Share Improve this question asked Apr 10, 2018 at 10:33 niklas-eniklas-e 4765 silver badges15 bronze badges 2
  • 1 have you looked at this post? stackoverflow./questions/704758/… – mrdeadsven Commented Apr 10, 2018 at 10:46
  • @mrdeadsven nope, but definitely worth testing. Thanks! – niklas-e Commented Apr 10, 2018 at 11:03
Add a ment  | 

1 Answer 1

Reset to default 13

Our solution was to use couple things to determine whether the element is visible and not behind any other elements. Here's the methods we used.

  1. window.getComputedStyle to check visibility:hidden and display:none
  2. document.elementFromPoint from multiple points. Most mon cases could probably be handled by checking all the corners. Though we needed more points to get more robust results. Corner coordinates can be easily checked with Element.getBoundingClientRect()

https://jsfiddle/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
}

Note: Node.contains returns true if the given element is the node itself or a descendant of it. If you want to check for only the exact element instead of including also it's descendants, you should use document.elementFromPoint(...) !== element for the conditional statements inside isBehindOtherElement

发布评论

评论列表(0)

  1. 暂无评论