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