Проблема с прокруткой параллакса - перетаскивание элемента div при прокрутке в браузерах webkit
Я создал прокрутку parallax, которая, кажется, работает нормально в firefox, однако в браузере Chrome есть небольшой прыжок по тексту тела при прокрутке. нажмите здесь, перейдите к разделу about. Я не уверен, что это проблема css или JS. Ниже приведен фрагмент, который я включил в свою функцию параллакса.
Кто-нибудь знает, как исправить эту проблему?
$(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.) Используйте position: fixed
, чтобы избежать какого-либо джиттера, поскольку вы будете вынимать элемент из потока документов. Затем вы можете расположить его с помощью z-index.
2.) Загрузите столько, сколько сможете, чтобы уменьшить время обработки.
3.) Math.round может не понадобиться, но попробуйте добавить этот CSS в свои движущиеся области: -webkit-transform: translate3d(0,0,0);
Это заставит аппаратное ускорение в Chrome, что может облегчить некоторые дрожания. (Это выглядело более плавным на моем экране, когда я добавил это с помощью Inspector, но он не избавился от прыжков с колесиком прокрутки.) Примечание. Не делайте этого на весь документ (например, тег тела), так как это может вызывают некоторые проблемы с вашим текущим макетом. (Например, ваша панель навигации не прилипала к верхней части окна.)
4.) Если у вас есть анимация, выполняемая как часть вашей логики параллакса (перемещение поля на место или что-то вдоль этих строк), удалите его - это, вероятно, вызовет скачок, который вы видите.
Надеюсь, это поможет. Удачи.
Ответ 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". Большинство из них (основная) идут к округленным значениям числа.
Ответ 3
Вам придется изменить способ работы прокрутки (т.е. изменить способ вычисления интервала), но это можно устранить, добавив элемент position:fixed
CSS к элементам страницы, которые прокручиваются. Проблема возникает с того времени, которое требуется для обработки JavaScript и последующего рендеринга.
Например, на вашей странице вы установите для каждого из тегов <div>
, содержащих текст, фиксированную позицию, а затем используйте функцию JavaScript/JQuery для обновления элемента CSS top:
. Это должно заставить страницу прокручиваться плавно.
Ответ 4
Вы пытались добавить предупреждение в функцию прокрутки?
$(window).scroll(function(e) {
e.preventDefault();
// rest of your code
}
Ответ 5
В предыдущем вопросе я создал довольно хорошую реализацию прокрутки параллакса. Jquery Parallax Эффект прокрутки - многонаправленный Вы можете найти его полезным.
Здесь JSFiddle http://jsfiddle.net/9R4hZ/40/ использует стрелки вверх/вниз или колесо прокрутки.
Использование отступов и полей для позиционирования, вероятно, связано с тем, что вы испытываете проблемы с рендерингом. В то время как мой код использует прокрутку или ввод с клавиатуры для эффекта, вы можете зацикливать разреженную часть и проверить переменную $move, пока не достигнете нужного элемента на экране.
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());
}