Почему Chrome для мобильных устройств не перерисовывает мой фиксированный заголовок?
У меня есть заголовок, который я хотел бы контролировать видимость при прокрутке. При прокрутке вниз страницы заголовок должен работать как любой элемент. При прокрутке страницы вверх, независимо от положения страницы, я хотел бы показать заголовок при подъеме страницы. Это поведение может быть лучше всего понято на простом примере.
Я слушаю события прокрутки и обновляю фиксированную позицию div с отрицательным верхним значением:
$(function()
{
var $header = $("#header");
var $window = $(window);
var headerHeight = $header.outerHeight();
var headerY = $header.outerHeight();
var scrollY = $window.scrollTop();
$window.on("scroll", function()
{
headerY += scrollY - $window.scrollTop();
if (headerY > headerHeight)
{
headerY = headerHeight;
}
else if (headerY < 0)
{
headerY = 0;
}
$header.css(
{
top: headerY - headerHeight,
});
scrollY = $window.scrollTop();
});
});
Тем не менее, поведение в Chrome для мобильных устройств совсем не то, что я ожидал. Заголовок часто не анимируется и мгновенно появляется или исчезает при достижении границ. Когда это действительно оживляет, производительность прерывисто нерегулярна и часто рисует только один - три кадра. Такое поведение не проявляется при использовании мобильной эмуляции рабочего стола Chrome; это происходит только на реальном устройстве.
Кажется, что это происходит только при работе с элементом фиксированной позиции в верхней части страницы. Если я пытаюсь изменить фиксированный элемент другим способом, например, перемещая его сбоку или снизу, все работает намного ближе к ожидаемому. Фактически, если я изменю как верхний элемент с фиксированной позицией, так и боковой элемент с фиксированной позицией, верхний элемент будет вести себя более равномерно, как это происходит.
Почему Chrome для мобильных устройств так нестабилен с элементами фиксированного положения вверху страницы? Есть ли способ, которым я могу объяснить это в сжатой форме?
2 ответа
Попробуйте использовать некоторые аппаратно ускоренные преобразования CSS3. Вместо того, чтобы использовать top
чтобы позиционировать свой элемент, попробуйте использовать transform:translateY
,
Также попробуйте добавить transform:translateZ(0)
на элементе заголовка.
Здесь много в игре. Мобильные устройства не такие мощные, как настольные компьютеры, и анимация иногда может показаться вялой. Особенно, когда на странице присутствуют тени CSS.
Я не уверен, что вызывает это, но я бы дал шанс window.requestAnimationFrame
функция всегда поддерживается (вам нужно проверить поддержку старых браузеров, таких как IE9).
Идея состоит в том, чтобы перерисовывать экран всякий раз, когда мобильный графический процессор готов перерисовать (обычно каждые 16,6 мс), а не заполнять его запросом, который не может быть обработан своевременно.
Поэтому я бы попробовал что-то вроде этого (не проверено):
$(function()
{
var $header = $("#header");
var $window = $(window);
var headerHeight = $header.outerHeight();
var headerY = $header.outerHeight();
var scrollY = $window.scrollTop();
var requestId;
$window.on("scroll", function()
{
//run only when no request is pending.
if (requestId === undefined) {
requestId = window.requestAnimationFrame(animateHeader);
}
});
function animateHeader() {
requestId = undefined;
headerY += scrollY - $window.scrollTop();
if (headerY > headerHeight)
{
headerY = headerHeight;
}
else if (headerY < 0)
{
headerY = 0;
}
$header.css(
{
top: headerY - headerHeight,
});
scrollY = $window.scrollTop();
}
});
Поскольку я не уверен, что это что-то решает, некоторые отзывы, как только вы попробовали, были бы хорошими!
- Отредактированное условие requestAnimationFrame должно быть вызвано.