1

http://codepen.io/leongaban/pen/YNBgqE

After you scroll the #tickers-col how do you get the correct updated top position of the div?

From the log no matter how far up the column goes, it still displays the original y position of the div:

enter image description here colPos Object {x: 8, y: 8}

const tickersCol = document.getElementById("tickers-col");


// https://stackoverflow.com/questions/288699/get-the-position-of-a-div-span-tag
function getPos(el) {
  for (var lx=0, ly=0;
       el != null;
       lx += el.offsetLeft, ly += el.offsetTop, el = el.offsetParent);
  return {x: lx,y: ly};
}

function mouseHover() {
  const colPos = getPos(tickersCol);
  console.log('colPos', colPos)
}
.container {
  position: fixed;
  font-family: Arial;
}

#tickers-col {
  overflow-y: auto;
  height: 400px;
}

li {
  margin-bottom: 10px;
  list-style: none;
  padding: 5px 10px;
  width: 120px;
  color: white;
  background: salmon;
  border-radius: 4px;
  cursor: pointer;
}
<div class="container">
<div id="tickers-col">
  <ul>
    <li onmouseenter="mouseHover()">aaa</li>
    <li onmouseenter="mouseHover()">bbb</li>
    <li onmouseenter="mouseHover()">ccc</li>
    <li onmouseenter="mouseHover()">ddd</li>
    <li onmouseenter="mouseHover()">eee</li>
    <li onmouseenter="mouseHover()">fff</li>
    <li onmouseenter="mouseHover()">ggg</li>
    <li onmouseenter="mouseHover()">hhh</li>
    <li onmouseenter="mouseHover()">iii</li>
    <li onmouseenter="mouseHover()">jjj</li>
    <li onmouseenter="mouseHover()">kkk</li>
    <li onmouseenter="mouseHover()">lll</li>
    <li onmouseenter="mouseHover()">mmm</li>
    <li onmouseenter="mouseHover()">nnn</li>
    <li onmouseenter="mouseHover()">ooo</li>
    <li onmouseenter="mouseHover()">ppp</li>
    <li onmouseenter="mouseHover()">qqq</li>
    <li onmouseenter="mouseHover()">rrr</li>
    <li onmouseenter="mouseHover()">sss</li>
    <li onmouseenter="mouseHover()">ttt</li>
    <li onmouseenter="mouseHover()">uuu</li>
    <li onmouseenter="mouseHover()">vvv</li>
    <li onmouseenter="mouseHover()">www</li>
    <li onmouseenter="mouseHover()">yyy</li>
    <li onmouseenter="mouseHover()">xxx</li>
    <li onmouseenter="mouseHover()">zzz</li>
  </ul>
</div>
</div>

Found the getPos function from here: Get the position of a div/span tag

Community
  • 1
  • 1
Leon Gaban
  • 36,509
  • 115
  • 332
  • 529

3 Answers3

1

Try the code blow.

Scroll and then hover on one of the divs, you can see the y-coordinate is getting updated.

const tickersCol = document.getElementById("tickers-col");


const getPos = (el) => {
  for (var lx=0, ly=0;
   el != null;
   lx += el.offsetLeft, ly += el.scrollTop, el = el.offsetParent);
  return { x:lx, y:ly };
}

function mouseHover() {
  const colPos = getPos(tickersCol);
  console.log('colPos', colPos)
}
.container {
  position: fixed;
  font-family: Arial;
}

#tickers-col {
  overflow-y: auto;
  height: 400px;
}

li {
  margin-bottom: 10px;
  list-style: none;
  padding: 5px 10px;
  width: 120px;
  color: white;
  background: salmon;
  border-radius: 4px;
  cursor: pointer;
}
<div class="container">
<div id="tickers-col">
  <ul>
    <li onmouseenter="mouseHover()">aaa</li>
    <li onmouseenter="mouseHover()">bbb</li>
    <li onmouseenter="mouseHover()">ccc</li>
    <li onmouseenter="mouseHover()">ddd</li>
    <li onmouseenter="mouseHover()">eee</li>
    <li onmouseenter="mouseHover()">fff</li>
    <li onmouseenter="mouseHover()">ggg</li>
    <li onmouseenter="mouseHover()">hhh</li>
    <li onmouseenter="mouseHover()">iii</li>
    <li onmouseenter="mouseHover()">jjj</li>
    <li onmouseenter="mouseHover()">kkk</li>
    <li onmouseenter="mouseHover()">lll</li>
    <li onmouseenter="mouseHover()">mmm</li>
    <li onmouseenter="mouseHover()">nnn</li>  
  </ul>
</div>
</div>

Let me know if this is what you wanted.

Fan Jin
  • 2,412
  • 17
  • 25
  • So I'm actually trying to get the y position of the `#tickers-col` it seems that the `colPos` here is the y position of the individual li? What I'm expecting is something like y:0 at the start, then when you scroll it keeps going higher since it's off screen now, so y:-200? – Leon Gaban Feb 14 '17 at 19:23
  • 1
    Ah, that makes it easier actually, I updated my code. – Fan Jin Feb 14 '17 at 21:42
1

So, I really don't understand what exactly you are trying to do but by definition the offsetTop property of an element will return the top position (in pixels) relative to the top of the offsetParent element.

So no matter how long you scroll, if the top distance between the element you are inspecting and it's parent does't change, your top value will not change.

Maybe the property you are looking for is scrollTop;

const getPos = (el) => {
    for (var lx=0, ly=0;
         el != null;
         lx += el.offsetLeft, ly += el.scrollTop, el = el.offsetParent);
    return { x:lx, y:ly };
}
Leon Gaban
  • 36,509
  • 115
  • 332
  • 529
  • Yes `scrollTop`! Yeah I'm trying to figure out what the new `y` is of the `tickers-col`. Just added it to this `lx += el.offsetLeft, ly += el.scrollTop, el = el.offsetParent);` testing to make sure it's correct. – Leon Gaban Feb 14 '17 at 19:26
0

After you scroll the #tickers-col how do you get the correct updated top position of the div?

div itself isn't moving when scrolling, instead only its direct children are moving.

So top position is : #ticker-col's offsetTop - ul's scrollTop , and your js code should look like this:

(function(){

var tc = document.querySelector("#tickers-col");

tc.addEventListener("scroll",function(){      
    console.log("colPos:", { x : tc.parentNode.offsetLeft,
                             y : tc.parentNode.offsetTop - tc.scrollTop,
                            });      
});



})();
.container {
  position: fixed;
  font-family: Arial;
}

#tickers-col {
  overflow-y: auto;
  height: 400px;
}

li {
  margin-bottom: 10px;
  list-style: none;
  padding: 5px 10px;
  width: 120px;
  color: white;
  background: salmon;
  border-radius: 4px;
  cursor: pointer;
}
<div class="container">
 <div id="tickers-col">
  <ul>
    <li>aaa</li>
    <li>bbb</li>
    <li>ccc</li>
    <li>ddd</li>
    <li>eee</li>
    <li>fff</li>
    <li>ggg</li>
    <li>hhh</li>
    <li>iii</li>
    <li>jjj</li>
    <li>kkk</li>
    <li>lll</li>
    <li>mmm</li>
    <li>nnn</li>
    <li>ooo</li>
    <li>ppp</li>
    <li>qqq</li>
    <li>rrr</li>
    <li>sss</li>
    <li>ttt</li>
    <li>uuu</li>
    <li>vvv</li>
    <li>www</li>
    <li>yyy</li>
    <li>xxx</li>
    <li>zzz</li>
  </ul>
 </div>
</div>

P.S.

onmouseenter="mouseHover()"

this thing looks ugly, if you need to set the same function for some number of elements > 2 as event listener the better approach would be like so

var collection =
Array.prototype.slice.call(
  document.querySelectorAll('mycssselector')
).forEach(function(el){
    el.addEventListener("myevent",/*callback*/function(){});
}); 
darkside
  • 47
  • 5