在没有jQuery的情况下模拟scrollTop效果

时间:2014-04-11 02:43:43

标签: javascript

我试图用JS模拟scrollTop效果。这是我正在使用的代码。此代码作为另一个此类问题的一部分发布在SO上。

 function scrollToTop(element, to, duration){
        if(duration<0) return;
        var difference = to - element.scrollTop;
        var perTick = difference/duration * 10;
        console.log("Logging diff" +difference);
        setTimeout(function(){
            console.log(perTick);
            console.log("Log before scroll"+element.scrollTop);
            element.scrollTop=(element.scrollTop + perTick);
            console.log("Log after scroll"+element.scrollTop);
            scrollToTop(element, to, duration-10);
        }, 10);
        }

现在即使我将perTick添加到element.scrollTop,当控制台日志显示添加不会发生时。

 console.log("Log before scroll"+element.scrollTop);

 console.log("Log after scroll"+element.scrollTop);

两者都显示0.我不知道我哪里出错了。请帮忙。

1 个答案:

答案 0 :(得分:0)

这是一种不同的方法。它运作良好,但我有疑问 - 我希望你做更多的事情,并报告你学到的东西。滚动是(似乎?)最平滑,延迟60ms。我认为这与18ticks / sec时钟有关吗?代码被评论。函数“lerp”(线性插值)是一个有用的函数 - 有些语言使它具有原生性。 (我没有足够的评论意见。)

[edit] Interesing link: http://ejohn.org/blog/accuracy-of-javascript-time/

<html>
<head>
<style type="text/css">
#buttons { position:fixed; left:100px; top:10px; }
#div1    { width:400px; height:100px; background:#eee; overflow:scroll; }
</style>
<script type="text/javascript">
function scrollto(elt, to, duration) { 
  if (duration < 0) return;
  console.log(to + " | " + elt.scrollHeight);
  if (to < 0 || to > elt.scrollHeight) return;
  var fm = elt.scrollTop;           // begin
  var time1 = new Date().getTime(); // begin
  var time9 = time1 + duration      // end
  scrollsub(elt, fm, to, time1, time9);
  }
function scrollsub(elt, fm, to, time1, time9) {
  console.log(fm + " | " + to + " | " + time1 + " | " + time9);
  var timenow = new Date().getTime();
  var k01 = (timenow - time1) / (time9 - time1);
  var whither = lerp(k01, fm, to);
  console.log(timenow + " | " + whither);
  if (timenow < time9) {
    elt.scrollTop = whither;
    setTimeout(scrollsub, 60, elt, fm, to, time1, time9); }
  else { elt.scrollTop = to; } // just finish
  }
function lerp(k01, k0, k1) { // linear interpolation
  return k0 + (k1 - k0) * k01; 
  }
function testgettime(time0, time) {
  var timenow = new Date().getTime() - time0;
  if (timenow != time) { 
    console.log(timenow/1000 + " | " + (timenow - time)/1000); }
  if (timenow < 2000) { // don't go forever 
    setTimeout(testgettime, 1, time0, timenow); }
  }
</script>
</head>
<body>
<div id="bodyid">
<div id="buttons">
  <button onclick="scrollto(getElementById('div1'), 150, 2000);">Scroll Down</button>
  <button onclick="scrollto(getElementById('div1'), 000, 2000);">Scroll Up</button>
  <button onclick="testgettime(new Date().getTime(), 0);">testgettime()</button>
</div>
x<br />x<br />x<br />x<br />x<br />x<br />x<br />x<br />x<br />x<br />
<div id="div1">
y1<br />y2<br />y3<br />y4<br />y5<br />y6<br />y7<br />y8<br />y9<br />10<br />
</div>
x<br />x<br />x<br />x<br />x<br />x<br />x<br />x<br />x<br />x<br />
</div>
</body>
</html>