How do I get the offset of an element from the current screen position?

I am trying to refactor my entire jQuery with pure Javascript, everything works for me except for a special value. I get a different value depending on the browser vendor for this code:

With jQuery, I would use:

var topSelected = figure.offset().top - $(window).scrollTop();

      

Here's my (not working) attempt at using the DOM without jQuery:

 var rect = figure.getBoundingClientRect(),
     topSelected = (rect.top + document.body.scrollTop) - window.pageYOffset;

      

I am getting the same value for topSelected in Chrome with this code, but not for FF. The value that is different from browser to browser document.body.scrollTop

.

What is the correct way to get the difference between the offset of an element and the top of the scroll using the DOM API?

I need to support IE9 +, Firefox and Chrome.

+2


source to share


2 answers


I found a solution for this:

var rect = figure.getBoundingClientRect(),
    topSelected = (rect.top + (document.documentElement.scrollTop || document.body.scrollTo)) - window.pageYOffset;

      

What it does is check the value document.documentElement.scrollTop

. In Chrome this always returns 0. So if 0 is returned, it document.body

is given as a function element scrollTop

outside the parenthesis.



TL; DR

To get the offset correctly:
Firefox -> document.documentElement
Chrome -> document.body

0


source


function getPosition(element) {
  var xPosition = 0,
    yPosition = 0;

  while (element) {
    xPosition += (element.offsetLeft + element.clientLeft);
    yPosition += (element.offsetTop + element.clientTop);
    element = element.offsetParent;
  }
  return {
    x: xPosition,
    y: yPosition
  };
}

function getScroll() {
  return {
    x: document.documentElement.scrollLeft || document.body.scrollLeft,
    y: document.documentElement.scrollTop || document.body.scrollTop
  };
}

document.getElementById('test').addEventListener('click', function() {
  var pos = getPosition(this),
    scroll = getScroll(),
    diff = (pos.x - scroll.x) + ',' + (pos.y - scroll.y);

  this.childNodes[0].nodeValue = diff;
  console.log(diff);
}, false);
      

body {
  height: 1000px;
  width: 1000px;
  font-family: Consolas, monospace;
}
#test {
  display: inline-block;
  border: 3px solid;
  padding: 10px;
  margin-top: 300px;
  margin-left: 300px;
}
      

<div id='test'>Element</div>
      

Run codeHide result


Summary:



The final set of functions might look like this:

function getPosition(element) {
    var xPosition = 0,
        yPosition = 0;

    while (element) {
        xPosition += (element.offsetLeft + element.clientLeft);
        yPosition += (element.offsetTop + element.clientTop);
        element = element.offsetParent;
    }
    return {
        x: xPosition,
        y: yPosition
    };
}

function getScroll() {
    return {
        x: document.documentElement.scrollLeft || document.body.scrollLeft,
        y: document.documentElement.scrollTop || document.body.scrollTop
    };
}

function getWindowOffset(element) {
    var pos = getPosition(element),
    scroll = getScroll();

    return {
            x: (pos.x - scroll.x),
            y: (pos.y - scroll.y)
    };
}

      

Then just call getWindowOffset()

your element to get its position relative to the window.

+1


source







All Articles