Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/428.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用jQuery动画滚动条闪烁 我的问题_Javascript_Jquery_Animation_Underscore.js - Fatal编程技术网

Javascript 使用jQuery动画滚动条闪烁 我的问题

Javascript 使用jQuery动画滚动条闪烁 我的问题,javascript,jquery,animation,underscore.js,Javascript,Jquery,Animation,Underscore.js,我正在为一个客户创建一个垂直网站,当大部分元素在视口中可见时,该客户希望让窗口“捕捉”到最近的页面。因此,如果页面85%可见,它应该滚动到100%可见 我的问题是,有时当滚动到视口的顶部或底部时,视口会“粘住”第一个或最后一个元素,从而阻止一些滚动事件,并导致非常明显的闪烁 这里有一把小提琴: 要再现错误,请使用滚动条滚动到页面底部。然后,用鼠标滚轮向上滚动。你应该看到闪烁。有时需要几次刷新或尝试,但问题的重现性很高 我不知道是什么导致了这个问题。请参阅下文,了解我的代码以及我迄今为止试图阻止它

我正在为一个客户创建一个垂直网站,当大部分元素在视口中可见时,该客户希望让窗口“捕捉”到最近的页面。因此,如果页面85%可见,它应该滚动到100%可见

我的问题是,有时当滚动到视口的顶部或底部时,视口会“粘住”第一个或最后一个元素,从而阻止一些滚动事件,并导致非常明显的闪烁

这里有一把小提琴: 要再现错误,请使用滚动条滚动到页面底部。然后,用鼠标滚轮向上滚动。你应该看到闪烁。有时需要几次刷新或尝试,但问题的重现性很高

我不知道是什么导致了这个问题。请参阅下文,了解我的代码以及我迄今为止试图阻止它的内容


我的代码 为了完成捕捉,我需要检测某个元素是否具有一定的可见百分比。因此,我在下面添加了一个jQuery函数,
isNearScreen
。我已经彻底测试了这个函数,据我所知,它返回了准确的结果

//Modification of http://upshots.org/javascript/jquery-test-if-element-is-in-viewport-visible-on-screen 
//Returns "true" if element is percent visible within the viewport
$.fn.isNearScreen = function(percent){

    var offset = 1 - percent;

    var win = $(window);

    var viewport = {
        top : win.scrollTop()
    };

    viewport.bottom = viewport.top + win.height();

    var bounds = this.offset();
    bounds.bottom = bounds.top + this.outerHeight();
    bounds.top = bounds.top;

    //If the element is visible
    if(!(viewport.bottom < bounds.top || viewport.top > bounds.bottom)){

        //Get the percentage of the element that's visible
        var percentage = (viewport.bottom - bounds.top) / this.height();

        //If it's greater than percent, but less than 1 + (1 - percent), return true;
        return (percentage > (1 - offset) && percentage < (1 + offset));
    }
    return false;

};
最后,我绑定到窗口的滚动事件

$(window).on('scroll', snap});
(极其简化的)HTML:


我试过的 我尝试了以下方法,但没有成功:

  • 在窗口上设置布尔值“preventSnap”,检查其状态,如果设置为false,则仅触发
    snap
    的动画部分。动画完成后,将其设置为true,然后在500毫秒后将其设置为false(这在理论上可以防止双重触发)
  • 在运行
    snap
    动画之前,在元素上调用
    .stop()
  • 在运行动画之前,在滚动事件上调用
    event.preventDefault()
  • 减少和增加我的<代码>\反盎司<代码>延迟有趣的是,较低的
    .debounce
    延迟(200-300ms)似乎会加剧问题,而较高的
    .debounce
    延迟(1000ms)似乎会解决问题。但是,这不是一个可接受的解决方案,因为它感觉等待页面“抓拍”的时间“很长”
  • 更改元素的高度

如果有任何其他信息我可以提供,请让我知道。我不知所措

我认为这是事件和
\uu.debounce
工作方式的组合。我注意到在小提琴(铬合金)中,元素在捕捉完成后很长一段时间都在“抖动”。如果将控制台日志放在快照事件处理程序中,您可以看到它在快照之后不断被调用,即使没有滚动输入

这一定是滚动动画本身设置了捕捉,我试图设置一个标志,以防止双重捕捉,并在动画完成后清除标志——但是,我认为这不起作用,因为
正在排队等待稍后发生的事件(在动画完成并清除标志后)

因此,需要做的是将其添加为快照处理程序的开始:

var nosnap = false;

var snap = _.debounce(function(event){

    // Don't snap if already animating ...
    if (nosnap) { nosnap = false; return; } 
    nosnap = true;

这将阻止动画直接触发下一个快照事件——但是,如果在动画期间再次滚动,将导致问题

所以,这有点像黑客。理想情况下,您希望能够知道是什么导致了滚动事件,并做出相应的反应,但没有简单的方法可以做到这一点


我绝对认为在处理第二个滚动事件时也需要停止动画

我认为这是事件和
\uu.debounce
工作方式的组合。我注意到在小提琴(铬合金)中,元素在捕捉完成后很长一段时间都在“抖动”。如果将控制台日志放在快照事件处理程序中,您可以看到它在快照之后不断被调用,即使没有滚动输入

这一定是滚动动画本身设置了捕捉,我试图设置一个标志,以防止双重捕捉,并在动画完成后清除标志——但是,我认为这不起作用,因为
正在排队等待稍后发生的事件(在动画完成并清除标志后)

因此,需要做的是将其添加为快照处理程序的开始:

var nosnap = false;

var snap = _.debounce(function(event){

    // Don't snap if already animating ...
    if (nosnap) { nosnap = false; return; } 
    nosnap = true;

这将阻止动画直接触发下一个快照事件——但是,如果在动画期间再次滚动,将导致问题

所以,这有点像黑客。理想情况下,您希望能够知道是什么导致了滚动事件,并做出相应的反应,但没有简单的方法可以做到这一点


我绝对认为在处理第二个滚动事件时也需要停止动画

尝试减少持续时间,我认为这与浏览器的渲染有关。我也遇到了同样的问题。请尝试缩短持续时间,我认为这与浏览器的渲染有关。我也有同样的问题。你说的卷轴触发快照是对的。jQuery scrollTop触发一个滚动事件。我目前正在使用上述解决方案的组合,只是做了一点修改。我没有立即设置
nosnap=false
,而是将其设置为超时。我还将event.preventDefault设置为动画长度的超时持续时间-在动画制作过程中禁止滚动,并且禁止捕捉
..debounce
上的延迟。这是相当骇人的,但它似乎正在发挥作用。在开始动画之前,我还会调用
.stop()
。提琴:酷,很高兴你找到了有效的东西。我仍然对正确的方法感到好奇,即检测是什么触发了每个滚动事件。。。也许其他人会对此有答案,或者我会做更多的研究,然后问一个不同的问题。你说的对,卷轴触发了快照。jQuery scrollTop触发一个滚动事件。我目前正在使用上述解决方案的组合,只是做了一点修改。我没有立即设置
nosnap=false
,而是将其设置为超时。我也设定了一个平衡点
.page{
    height: 750px;
    width: 100%;
    margin: 10px 0;
    background: gray;
}

.page-contents{
    height: 100%;
    width: 100%;
}
var nosnap = false;

var snap = _.debounce(function(event){

    // Don't snap if already animating ...
    if (nosnap) { nosnap = false; return; } 
    nosnap = true;