使用setInterval()而不是setTimeout()滚动动画

时间:2013-05-07 12:17:16

标签: javascript


我想使用以下脚本在我的网站上为平滑的身体滚动设置动画:

function autoScroll(el) {
    var scrollY = 0;
    var distance = 2;
    var speed = 10;

    var scrolling = function(){
        var currentY = window.pageYOffset;
        var targetY = document.getElementById(el).offsetTop;
        var bodyHeight = document.body.offsetHeight;
        var yPos = currentY + window.innerHeight;
        var animator = setInterval('autoScroll(\''+el+'\')', speed)
        interval = animator;

        if (yPos > bodyHeight){
            clearInterval(animator);
        }else{
            if (currentY < targetY - distance){
                scrollY = currentY + distance;
                window.scrollTo(0, scrollY);
            }else if (currentY > targetY + distance){
                scrollY = currentY - distance;
                window.scrollTo(0, scrollY);
            }else{
                clearInterval(animator);
            }
        }
    }
    return scrolling();
}

脚本运行,但行为不端。当我第一次点击菜单时,它会很好地滚动到正确的位置,然后滚动停止。但是当我第二次点击菜单时,脚本永远不会停止滚动,并且它会尝试以同步方式同时向两个方向滚动。奇怪的是,当我使用setTimeout()和clearTimeout()函数而不是setInterval()和cleatIntervaw时,函数工作得很好。它必须是setInterval()的原因是因为动画比我使用setTimeout()时更加快捷。 有人可以向我解释为什么会出现这种异常以及如何解决这个问题吗? 赞赏
贾里德

UPDATE
这是我用来滚动的html标记:

<a href="#" class="scroll" onclick="return false;" onmousedown="autoScroll('location');"><div class="tableLink">Location</div></a>
...
<div id="location" class="page">location</div>

2 个答案:

答案 0 :(得分:0)

也许你需要在调用函数时清除间隔?

function autoScroll(el) {
    if (window.interval) window.clearInterval(interval);

答案 1 :(得分:0)

我看起来你做了一个比必要的更复杂的解决方案。每个间隔创建一个新函数然后返回的事实看起来有点奇怪。

您可以将问题分解为两个:

  1. 首先设置目标元素。
  2. 然后使用setInterval启动一次循环(仅当它没有运行时),将页面向目标滚​​动直到达到目标(即使目标在循环中间变化,代码也可以写入工作)
  3. 此外,为了获得最流畅的体验,您应该考虑使用requestAnimationFrame而不是setInterval。

    最后,如果你不介意使用jQuery,那么很多插件已经提供了这个功能,比如http://demos.flesler.com/jquery/scrollTo/。可能值得一试。