【问题标题】:How to get updated top position of scrolled up div?如何获取向上滚动的 div 的更新顶部位置?
【发布时间】:2017-07-03 02:24:13
【问题描述】:

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

滚动#tickers-col 后,如何获得正确更新的 div 顶部位置?

从日志来看,无论该列往上走多远,它仍然显示 div 的原始y 位置:

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>

从这里找到getPos 函数:Get the position of a div/span tag

【问题讨论】:

    标签: javascript css mouseevent css-position


    【解决方案1】:

    试试代码。

    滚动然后将鼠标悬停在其中一个 div 上,您可以看到 y 坐标正在更新。

    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>

    如果这是你想要的,请告诉我。

    【讨论】:

    • 所以我实际上是在尝试获取#tickers-col 的y 位置,似乎colPos 这里是单个li 的y 位置?我期待的是一开始的 y:0 之类的东西,然后当你滚动它时,它会继续走高,因为它现在不在屏幕上,所以 y:-200?
    • 啊,这实际上更容易,我更新了我的代码。
    【解决方案2】:

    所以,我真的不明白你到底想做什么,但根据定义,元素的 offsetTop 属性将返回相对于 offsetParent 元素顶部的顶部位置(以像素为单位)。

    所以无论你滚动多久,如果你正在检查的元素和它的父元素之间的顶部距离没有改变,你的顶部值也不会改变。

    也许你要找的属性是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 };
    }
    

    【讨论】:

    • 是的scrollTop!是的,我想弄清楚tickers-col 的新y 是什么。只需将其添加到此 lx += el.offsetLeft, ly += el.scrollTop, el = el.offsetParent); 测试以确保其正确无误。
    【解决方案3】:

    滚动 #tickers-col 后,如何获得正确更新的 div 顶部位置?

    div 本身在滚动时不会移动,而只有其直接子级在移动。

    所以顶部位置是:#ticker-col's offsetTop - ul's scrollTop,你的 js 代码应该是这样的:

    (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>

    附言

    onmouseenter="mouseHover()"
    

    这东西看起来很丑,如果你需要为一些 > 2 的元素设置相同的函数作为事件监听器,更好的方法是这样

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

    【讨论】:

    • 我运行了你的 sn-p 并且它抛出了错误。你能在 codepen 中复制这个吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多