Javascript WebKit中带滚轮的抖动视差

Javascript WebKit中带滚轮的抖动视差,javascript,jquery,css,webkit,parallax,Javascript,Jquery,Css,Webkit,Parallax,我有一些视差背景的问题。我为我的一些朋友组织的一个活动制作了一个小网站,在这个网站上,我有一堆背景图片在内容部分之间交替出现。我添加了一些逻辑来抵消滚动时的背景图像,以创建视差效果 它工作得很好,我没有注意到任何性能问题,但是当使用滚轮时,视差在WebKit浏览器中似乎落后了 以下是该网站的链接: 我尝试模仿的效果,至少是背景图像,是在Spotify网站上看到的效果: 从他们的源代码来看,我似乎做了或多或少相同的事情:我有一个视差函数,它根据文档的scrollTop值计算背景变换,该函数被限

我有一些视差背景的问题。我为我的一些朋友组织的一个活动制作了一个小网站,在这个网站上,我有一堆背景图片在内容部分之间交替出现。我添加了一些逻辑来抵消滚动时的背景图像,以创建视差效果

它工作得很好,我没有注意到任何性能问题,但是当使用滚轮时,视差在WebKit浏览器中似乎落后了

以下是该网站的链接:

我尝试模仿的效果,至少是背景图像,是在Spotify网站上看到的效果:

从他们的源代码来看,我似乎做了或多或少相同的事情:我有一个视差函数,它根据文档的
scrollTop
值计算背景变换,该函数被限制为16毫秒,并绑定到窗口的滚动事件。不过,Spotify网站上的背景变换是即时的,而我的背景变换在视觉上落后于内容。它不是“坏的”,因为它在Firefox/IE中运行良好,在WebKit浏览器中手动滑动滚动条时也能正常工作。。。但这真的很烦人

有没有人知道是什么导致了这种抽搐

下面是视差功能的代码(我使用prototype,对
这个
垃圾邮件感到非常抱歉):


我最近根据Spotify的网站重新创建了我自己的视差效果,我遇到了您在这里提到的许多问题

虽然我无法完全摆脱Safari上的口吃,但我已经设法在Chrome和Firefox上以60 fps的速度平稳运行

我在这里将其作为jQuery插件发布,但您可以调整它以使用您选择的框架:

有几个技巧可以帮助我优化它:

  • 尽可能避免

  • ,延迟到设置超时或调用

  • 利用
    位置:固定。在有点滞后的浏览器上,结巴将是最小的

  • 使用强制浏览器分层,但要谨慎

  • 探索诊断瓶颈


  • 这些帮助我摆脱了在我自己的实现中看到的大部分口吃。

    这只是一个猜测,因为我曾经遇到过类似的问题。也许当你的scroll事件触发窗口时(在webkit中)没有重新计算jet,所以你会在该帧中得到旧值。尝试从scroll事件而不是从窗口获取滚动的数量。很抱歉给你一个模糊的提示,我只在WebGL中使用它,不用于CSS动画,而且我对jQuery也不太熟悉。据我所知,从scroll事件中获取scrollTop值的唯一方法是通过事件对象的
    target
    (或
    srcElement
    )属性访问它,例如:
    e.target.document.body.scrollTop
    。但是,文档节点将与用于调用jQuery的
    scrollTop()
    的节点相同,因此我不会有同样的问题吗?你是对的,我想我把scroll与wheel事件混淆了,事件中有一个wheel delta值。但是通过查看源代码和一步一步的调试,我意识到调用jQuery的“throttle”(出于某种原因,它发生在某个地方)会导致所有事情都以异步方式发生,超时时间为1ms。可能是这导致了问题?好吧,我可能只是遇到了一个类似的问题,我通过从窗口而不是从文档中获取值来解决它。也许这对你的案子也有用。谢谢,我回家后会试试看,让你知道结果如何。
        parallaxBackground: function () {
            var viewportTop = this.elements.$document.scrollTop();
            var viewportBottom = viewportTop + this.elements.$window.height();
            var scrollDelta = this.slideHeight + this.elements.$window.height();
    
            $.each( this.backgroundSlides, function ( index, slide ) {
                var slideTop = slide.$container.offset().top;
                var slideBottom = slideTop + this.slideHeight;
                if ( slideBottom < viewportTop || slideTop > viewportBottom )
                    return true;
                var factor = 1 - ( slideBottom - viewportTop ) / scrollDelta;
                this.transformBackground( slide.$image, this.slideLength * ( factor - 1 ) );
            }.bind( this ) );
        },
    
        transformBackground: Modernizr.csstransforms ? function ( $backgroundElement, distance ) {
            $backgroundElement.css( {
                '-ms-transform': 'translate(0px, ' + distance + 'px)',
                '-webkit-transform': 'translate(0px, ' + distance + 'px)',
                'transform': 'translate(0px, ' + distance + 'px)'
            } );
        } : function ( $backgroundElement, distance ) {
            $backgroundElement.css( 'top', distance );
        }
    
    this.elements.$window.on( 'scroll',
        _.throttle( this.parallaxBackground.bind( this ), 16 ) );