1

Someone knows how to reference the "nearest to the top" dom element currently on visible screen?

Something like this solution: How to get first visible DOM element currently showing on the screen? ; but purely on javascript.

Don't care about position coords, nor anything else, than just get reference to it.

Thanks in advance

NBK
  • 58
  • 5
  • The linked question uses JavaScript, what do you mean "purely in JavaScript"? – amn Sep 18 '19 at 12:05
  • probably mean without jQuery – Calvin Nunes Sep 18 '19 at 12:07
  • 2
    Is this something that needs to be calculated frequently (on scroll, for instance)? If so, you might find [`IntersectionObserver`](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) useful. – spender Sep 18 '19 at 12:07
  • @amn I mean, no libraries involved (E.g. jQuery – NBK Sep 19 '19 at 13:59
  • @spender Rite. That's why I pointed "element currently on visible screen". Thaks for your note!! – NBK Sep 19 '19 at 14:01

2 Answers2

2

This is basically the same code as this answer but without jQuery.

function visible(elem) {
  return !(elem.clientHeight === 0 || elem.clientWidth === 0)
}

let first;
let firstOffY;
let allVisible = Array.from(document.querySelectorAll('body > *')).filter(visible)
for(const elem of allVisible) {
  //Calculaate the offset to the document 
  //See: https://stackoverflow.com/a/18673641/7448536
  const offY = elem.getBoundingClientRect().top + document.documentElement.scrollTop
  if (first == null || offY < firstOffY) {
    first = elem;
    firstOffY = offY;
  }
}

first.classList.add('highlight');
.highlight {
  background-color: yellow;
}
<div>
  <p>Some Text</p>
  <h1>Headline</h1>
</div>
  • document.querySelectorAll('body > *') Select all elements under body
  • Array.from Convert the return value of querySelectorAll to a real array
  • .filter(visible) discard all elements that are not visible
Wendelin
  • 2,206
  • 1
  • 9
  • 24
1

In case you need better compatibility, here a bit adjusted Wendelin's answer.

function visible(elem) {
  return !(elem.clientHeight === 0 || elem.clientWidth === 0)
}

let first;
let firstOffY;
var elems = [], source = document.querySelectorAll('body > *');
for(var elemI=0;elemI<source.length;elemI++) {
   elems.push(source[elemI]);
}
let allVisible = elems.filter(visible)
for(var elem in allVisible) {
  elem = allVisible[elem];
  //Calculaate the offset to the document 
  //See: https://stackoverflow.com/a/18673641/7448536
  const offY = elem.getBoundingClientRect().top + document.documentElement.scrollTop
  if (first == null || offY < firstOffY) {
    first = elem;
    firstOffY = offY;
  }
} 

console.log(first.outerHTML);
first.classList.add('highlight');
.highlight {
  background-color: yellow;
}
<div>
  <p>Some Text</p>
  <h1>Headline</h1>
</div>
Tom
  • 1,950
  • 3
  • 12
  • 23