2012-11-18 187 views
17

我已经创建了一个视差滚动,它似乎在Firefox中正常工作,但是在Chrome浏览器中滚动时正文文本略有跳动。 click here scroll to the about section。我不知道这是一个CSS或JS问题..下面是我已经纳入我的视差功能的片段视差滚动问题 - 在webkit浏览器中滚动时div元素跳动

有谁知道我该如何解决这个问题?

$(document).ready(function(){ 

// Cache the Window object 
$window = $(window); 

// Cache the Y offset and the speed of each sprite 
$('[data-type]').each(function() { 
    $(this).data('offsetY', parseInt($(this).attr('data-offsetY'))); 
    $(this).data('Xposition', $(this).attr('data-Xposition')); 
    $(this).data('speed', $(this).attr('data-speed')); 
}); 

// For each element that has a data-type attribute 
$('[data-type="background"]').each(function(){ 


    // Store some variables based on where we are 
    var $self = $(this), 
     offsetCoords = $self.offset(), 
     topOffset = offsetCoords.top; 


    // When the window is scrolled... 
    $(window).scroll(function() { 

     // If this section is in view 
     if (($window.scrollTop() + $window.height()) > (topOffset) && 
      ((topOffset + $self.height()) > $window.scrollTop())) { 

      // Scroll the background at var speed 
      // the yPos is a negative value because we're scrolling it UP!        
      var yPos = -($window.scrollTop()/$self.data('speed')); 

      // If this element has a Y offset then add it on 
      if ($self.data('offsetY')) { 
       yPos += $self.data('offsetY'); 
      } 

      // Put together our final background position 
      var coords = '50% '+ yPos + 'px'; 

      // Move the background 
      $self.css({ backgroundPosition: coords }); 

      $('[data-type="scroll-text"]', $self).each(function() { 
        var $text= $(this); 
        var pos = ($window.scrollTop()/10) * $text.data('speed'); 
        var curP = $text.css('margin-top'); 
        var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1; 
        if(is_chrome) { 
         $text.animate({ 
         paddingTop: pos, 
         }, 200, 'linear', function() { 
          // Animation complete. 
         }); 
        } else { 
        $text.css('padding-top', pos); 
        } 
      }); 

     }; // in view 

    }); // window scroll 

}); // each data-type 


     }); // document ready 
+1

您的代码将受益于简单的优化:1)调用'$(窗口).scrollTop()'只是一次并缓存值,2)查询DOM的'[数据文本]'之外的元素的事件监听者。 –

+0

@IanKuca你可以详细说明这个升技,甚至可以编辑github上的JS。我不是最大的Javascript – NewBoy

+0

http://pastebin.com/JCaA7T6A –

回答

1

你将不得不改变了滚动的作品(即更改间距是如何计算的)的方式,但是这可以通过添加position:fixed CSS元素被滚动的页面元素进行固定。问题来自于JavaScript处理和渲染所花费的时间。

例如,在您的页面上,您将设置包含文本的每个<div>标签具有固定位置,然后使用JavaScript/JQuery函数更新top: CSS元素。这应该使页面滚动顺畅。

2

我在FireFox和Chrome(Mac)中看到了相同的抖动。看着你的容器,有一件事让我目瞪口呆,就是正在计算/使用的像素位置。

Chrome: <div id="about-title" style="margin-top: 1562.3999999999999px;"> 
FireFox: <div id="about-title" style="margin-top: 1562.4px;"> 

浏览器不会允许内容坐在1/2像素,更不用说0.3999999的像素。我认为它正在移动它,并试图计算是否收尾。它会因为每次点击鼠标滚轮而计算出来而产生抖动。

因此,我会尝试将Math.round()添加到您的位置,以便容器永远不会处于闲置状态。

看看这里的代码:http://webdesigntutsplus.s3.amazonaws.com/tuts/338_parallax/src/index.html

Firebug的一些元素,你会看到他们的一个像素的唯一分数为“0.5”。他们中的大多数(大部分)都是整数值。

+0

如果你真的快速滚动并“卡”到顶部,那么一些元素会失去同步并可能失去数百个像素,我遇到了问题。这完美解决了这个问题!谢谢! – Skovy

1

您是否尝试过在scroll功能中添加preventdefault?

$(window).scroll(function(e) { 
    e.preventDefault(); 
    // rest of your code 
} 
3

几点建议:

1)使用position: fixed以避免任何抖动,因为你将采取的元素出文档流程。然后你可以使用z-index来定位它。 2)缓存尽可能多的缓存处理时间。 3.)Math.round可能不是必需的,但可以尝试将CS​​S添加到移动区域:-webkit-transform: translate3d(0,0,0);这将强制在Chrome中进行硬件加速,这可能会缓解一些抖动。 (当我使用Inspector添加这个功能时,它在我的屏幕上看起来更平滑,但它没有摆脱滚轮的跳动。)注意:不要在整个文档(例如body标签)上这样做,因为它可能会导致您的当前布局存在一些问题。 (例如,您的导航栏并未粘贴到窗口顶部。)

4.)如果您有任何动画作为视差逻辑的一部分运行(将边距补充到位或沿着这些线条的某处) ,删除它 - 这可能会导致你看到的跳跃。

希望这会有所帮助。祝你好运。

+0

不确定它是否重要,但是,因为问题是要求“webkit”浏览器 - iOS Safari和Android Chrome都无法处理位置:固定。不确定移动设备是否重要,但它们是Webkit浏览器。 iOS 5和iOS 6稍微好一点,但iOS 4和最新的Android版本对待位置固定得很差 – netpoetica

+0

我有一个抖动问题和位置:fixed对我有用。谢谢! – William

+0

我有一个视差滚动只发生在Chrome(Win7)相关的问题。我的元素正在被重新定位'onscroll',并且一切都调整正确,但是当我使用鼠标滚轮进行滚动时(仅使用鼠标滚轮),视口的整个顶部/底部边缘将跳跃大约100px左右,就像浏览器窗口中没有内容的透明区域(您知道,即灰色/白色格子图案)。这个小故障会很快重复......您向移动元素添加'-webkit-transform:translate3d(0,0,0);'的建议解决了我的问题。 – seebigs

0

在上一个问题中,我创建了一个相当不错的视差滚动实现。 Jquery Parallax Scrolling effect - Multi directional您可能会觉得它很有用。

这里是JSFiddle http://jsfiddle.net/9R4hZ/40/使用向上/向下箭头或滚轮。

使用填充和边距进行定位可能是您遇到渲染问题的原因。虽然我的代码使用滚动或键盘输入的效果,你可以循环relavent部分,并检查$移动变量,直到你到达屏幕上的所需元素。

function parallaxScroll(scroll) { 
    // current moving object 
    var ml = $moving.position().left; 
    var mt = $moving.position().top; 
    var mw = $moving.width(); 
    var mh = $moving.height(); 
    // calc velocity 
    var fromTop = false; 
    var fromBottom = false; 
    var fromLeft = false; 
    var fromRight = false; 
    var vLeft = 0; 
    var vTop = 0; 
    if($moving.hasClass('from-top')) { 
     vTop = scroll; 
     fromTop = true; 
    } else if($moving.hasClass('from-bottom')) { 
     vTop = -scroll; 
     fromBottom = true; 
    } else if($moving.hasClass('from-left')) { 
     vLeft = scroll; 
     fromLeft = true; 
    } else if($moving.hasClass('from-right')) { 
     vLeft = -scroll; 
     fromRight = true; 
    } 
    // calc new position 
    var newLeft = ml + vLeft; 
    var newTop = mt + vTop; 
    // check bounds 
    var finished = false; 
    if(fromTop && (newTop > t || newTop + mh < t)) { 
     finished = true; 
     newTop = (scroll > 0 ? t : t - mh); 
    } else if(fromBottom && (newTop < t || newTop > h)) { 
     finished = true; 
     newTop = (scroll > 0 ? t : t + h); 
    } else if(fromLeft && (newLeft > l || newLeft + mw < l)) { 
     finished = true; 
     newLeft = (scroll > 0 ? l : l - mw); 
    } else if(fromRight && (newLeft < l || newLeft > w)) { 
     finished = true; 
     newLeft = (scroll > 0 ? l : l + w); 
    } 
    // set new position 
    $moving.css('left', newLeft); 
    $moving.css('top', newTop); 
    // if finished change moving object 
    if(finished) { 
     // get the next moving 
     if(scroll > 0) { 
      $moving = $moving.next('.parallax'); 
      if($moving.length == 0) 
       $moving = $view.find('.parallax:last'); 
     } else { 
      $moving = $moving.prev('.parallax'); 
      if($moving.length == 0) 
       $moving = $view.find('.parallax:first'); 
     } 
    } 
    // for debug 
    $('#direction').text(scroll + " " + l + "/" + t + " " + ml + "/" + mt + " " + finished + " " + $moving.text()); 
}