Некоторые (веб-сайт) эффекты прокрутки настолько завораживают, но вы не знаете, как их добиться, эта статья расскажет о них для вас. Мы познакомим вас с новейшими функциями JavaScript и CSS, основанными на новейших технологиях и спецификациях, которые (когда вы примените их на практике) сделают прокрутку ваших страниц более плавной, улучшат внешний вид и повысят производительность.
Содержимое большинства веб-страниц не может быть полностью отображено на одном экране, поэтому пользователям необходима прокрутка. Для интерфейсных инженеров и UX-дизайнеров обеспечение хорошей прокрутки в браузерах при соблюдении дизайна (требований), несомненно, является сложной задачей. В то время как веб-стандарты развиваются намного быстрее, чем когда-либо, реализация кода часто отстает. Далее вы познакомитесь с некоторыми распространенными вариантами использования прокрутки и проверите, не было ли используемое вами решение заменено более элегантным.
выцветшая полоса прокрутки
За последние три десятилетия внешний вид полосы прокрутки соответствовал меняющимся тенденциям в дизайне, поскольку дизайнеры (полосы прокрутки) цвета, теней, округлых форм и рамок со стрелками вверх и вниз экспериментировали с различными стилями. Ниже приводится изменение курса в Windows:
(полоса прокрутки в Windows)
В 2011 году дизайнеры Apple черпали вдохновение в iOS, чтобы задать направление определения «красивых» полос прокрутки. Все полосы прокрутки исчезают с компьютеров Mac, больше не занимают места на странице и снова появляются только тогда, когда пользователь запускает прокрутку (полосы прокрутки) (некоторые пользователи не скрывают полосы прокрутки).
(полоса прокрутки на Mac)
Тихое исчезновение полосы прокрутки не раздражало фанатов Apple, а пользователи, привыкшие к тому, как прокручивается на iPhone и iPad, быстро привыкли к дизайну. Большинство разработчиков и дизайнеров считают это «хорошей новостью», потому что вычисление ширины полосы прокрутки может быть рутинной работой.
Однако мы живем в мире со многими операционными системами и браузерами, все из которых имеют разные реализации (для прокрутки). Если вы веб-разработчик, как и мы, вы не можете игнорировать «проблему с полосой прокрутки».
Вот несколько советов, которые помогут вашим пользователям лучше работать с прокруткой.
скрытый, но прокручиваемый
Давайте взглянем на классический пример модального окна. При его открытии главная страница должна перестать прокручиваться. В CSS есть следующие сочетания клавиш:
body {
overflow: hidden;
}
Но приведенный выше код имеет небольшой нежелательный побочный эффект:
(обратите внимание на красную обрезную головку)
В этом примере в демонстрационных целях мы установили полосу прокрутки так, чтобы она отображалась принудительно в системе Mac, чтобы взаимодействие с пользователем было похоже на взаимодействие с пользователями Windows.
Как мы можем решить эту проблему? Если мы знаем ширину полосы прокрутки, мы можем установить небольшое поле справа от главной страницы каждый раз, когда появляется модальное окно.
Поскольку разные операционные системы и браузеры имеют разную ширину полосы прокрутки, получить ее ширину непросто. В системе Mac, независимо от любого браузера (полоса прокрутки) имеет одинаковый размер 15px, но система Windows может свести разработчиков с ума:
(ширина "ста цветущих цветов")
Обратите внимание, что приведенные выше результаты основаны только на последней версии браузера (проверенной) под Windows. Предыдущая (браузерная) версия (ширина) может быть другой, и никто не знает, как изменится будущая (ширина полосы прокрутки).
Вместо того, чтобы угадывать (ширину полосы прокрутки), вы можете вычислить ее ширину через JavaScript. width):
const outer = document.createElement('div');
const inner = document.createElement('div');
outer.style.overflow = 'scroll';
document.body.appendChild(outer);
outer.appendChild(inner);
const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;
document.body.removeChild(outer);
Хотя это всего семь строк кода (которые измеряют ширину полосы прокрутки), есть несколько строк кода, которые манипулируют DOM. (Из соображений производительности) Избегайте манипуляций с DOM без необходимости.
Еще один способ решить эту проблему — сохранить полосу прокрутки при появлении модального окна Вот чистая реализация CSS, основанная на этой идее:
html {
overflow-y: scroll;
}
Хотя проблема «дрожания модального окна» решена, на общий внешний вид влияет непригодная для использования полоса прокрутки, что, несомненно, является недостатком дизайна.
На наш взгляд, лучшее решение — полностью скрыть полосу прокрутки. Также возможно сделать это чисто с помощью CSS. Этот метод (достигаемый эффект) не совсем такой же, как в macOS, и полоса прокрутки по-прежнему невидима при прокрутке (когда пользователь). Полосы прокрутки всегда невидимы, но страницы можно прокручивать. Для Chrome, Safari и Opera можно использовать следующий CSS:
.container::-webkit-scrollbar {
display: none;
}
Следующий код доступен для IE или Edge:
.container {
-ms-overflow-style: none;
}
Что касается Firefox, то, к сожалению, нет возможности скрыть полосы прокрутки.
Как видите, серебряной пули не существует. У любого решения есть свои плюсы и минусы, и вам следует выбрать наиболее подходящее, исходя из потребностей вашего проекта.
Споры о внешнем виде
Следует признать, что внешний вид полосы прокрутки выглядит не очень хорошо в некоторых операционных системах. Некоторым дизайнерам нравится иметь полный контроль над стилями, которые они (дизайн) применяют, не упуская ни малейшей детали. существуетСотни репозиториев на GitHubИспользуйте JavaScript, чтобы заменить стандартную реализацию системной полосы прокрутки для пользовательских эффектов.
Но что, если вы хотите настроить полосу прокрутки на основе существующего браузера? (К сожалению,) общего API нет, каждый браузер имеет свою уникальную реализацию кода.
Хотя браузеры IE после версии 5.5 позволяют изменять стиль полосы прокрутки, они позволяют изменять только цвет полосы прокрутки. Вот код, как перерисовать (полосу прокрутки) раздел перетаскивания со стрелками:
body {
scrollbar-face-color: blue;
}
Но простое изменение цвета мало помогает пользователю. Исходя из этого, разработчики WebKit в 2009 году предложили схему стиля (модифицированная полоса прокрутки). Используется следующее-webkit
Код префикса, который эмулирует стили полосы прокрутки macOS в браузерах, поддерживающих соответствующие стили:
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-thumb {
background-color: #c1c1c1;
border-radius: 4px;
}
Chrome, Safari, Opera и даже UC Browser или собственный настольный браузер Samsung поддерживают (вышеупомянутый CSS). КрайТакже есть планы по их реализации.. Но спустя три года план по-прежнему имеет средний приоритет (и его еще предстоит реализовать).
Когда мы говорим о настройке полосы прокрутки, Mozilla Foundation в основном игнорирует потребности дизайнеров. (есть разработчики)17 лет назадЗапрос на изменение стиля полосы прокрутки уже сделан. И всего несколько месяцев назад Джефф Гриффитс (директор браузера Firefox) наконец-то ответил на этот вопрос:
«Меня это не волнует, если кто-то из команды не заинтересован в этом».
Честно говоря, с точки зрения W3C, несмотря на то, что реализация WebKit широко поддерживается, она все же не является стандартом. Существующий черновик для стилизации полосы прокрутки основан на IE: можно изменить только ее цвет.
Поддерживает изменение стиля полосы прокрутки, как это делает WebKit с запросами.issue, полемика продолжается. Если вы хотите повлиять на рабочую группу CSS, самое время принять участие. Возможно, это не первоочередная проблема, но стандартизация (изменение стилей полосы прокрутки, например, WebKit) значительно облегчит жизнь многим фронтенд-инженерам и дизайнерам.
Опыт бесперебойной работы
Для прокрутки наиболее распространенной задачей является навигация (переход) целевой страницы. Обычно это делается через анкорные ссылки. Просто нужно знать элементid
Только что:
<a href="#section">Section</a>
Щелкнув по этой ссылке, выПрыгатьк блоку (соответствующему якорю), (однако) дизайнеры UX обычно настаивают на том, чтобы процесс шел гладко.На GitHub есть тонны встроенных колес.(чтобы помочь вам с этим), однако все они в большей или меньшей степени используют JavaScript. (На самом деле) того же эффекта можно добиться всего одной строкой кода, недавно в DOM APIElement.scrollIntoView()
в состоянии пройтиПередайте объект конфигурациидля плавной прокрутки:
elem.scrollIntoView({
behavior: 'smooth'
});
Однако это свойствоплохая совместимостьИ еще через скрипт (контролировать стиль). Дополнительные сценарии следует использовать экономно, если это возможно.
К счастью, есть совершенно новыйCSS-свойства(все еще в рабочем проекте), поведение прокрутки всей страницы можно изменить с помощью простой строки кода.
html {
scroll-behavior: smooth;
}
Результат выглядит следующим образом:
(перепрыгнуть с одного блока на другой)
(плавно листать)
ты сможешь codepen Поэкспериментируйте с этим свойством выше. На момент написания этой статьиscroll-behavior
Поддерживается только в Chrome, Firefox и Opera, но мы ожидаем, что он будет широко поддерживаться, потому что использование CSS (чем использование JavaScript) намного элегантнее в решении проблем с прокруткой страницы и больше соответствует "прогрессивное улучшение" Режим.
Липкий CSS
Другим распространенным требованием является динамическая привязка элементов на основе направления прокрутки, известная как «липкость» (т. е. в CSS).position: sticky
)"эффект.
(липкий элемент)
Раньше для реализации «липкого» элемента требовалось писать сложные обработчики прокрутки для расчета размера элемента. (Однако) эта функция сложнее справляется с крошечными задержками между «залипанием» и «не залипанием» элементов, (часто) вызывая появление дрожания (элемента). Выполнение этого с помощью JavaScript («липкие» элементы) также имеет проблемы с производительностью, особенно когда (требуется) вызов [Element.getBoundingClientRect()
]Время(developer.Mozilla.org/en-US/docs/…
Не так давно CSS реализовалposition: sticky
Атрибуты. Мы можем добиться того, чего хотим, просто указав смещение (в определенном направлении).
.element {
position: sticky;
top: 50px;
}
(После написания приведенного выше кода) остальное остается реализовать браузеру. ты сможешь codepen Проверьте это. На момент написания этой статьиposition: sticky
Он хорошо поддерживается в различных браузерах (включая мобильные браузеры), поэтому, если вы все еще используете JavaScript для решения этой проблемы, пришло время переключиться на чистую реализацию CSS.
Полное использование функции дросселирования
С точки зрения браузера прокрутка — этомероприятие, поэтому в JavaScript используется стандартизированный прослушиватель событийaddEventListener
разобраться с этим: ,
window.addEventListener('scroll', () => {
const scrollTop = window.scrollY;
/* doSomething with scrollTop */
});
Пользователи склонны прокручивать (страницы) с высокой частотой, но если событие прокрутки запускается слишком часто, это вызовет проблемы с производительностью, которые можно решить с помощьюрегулирование функцииЭтот трюк, чтобы оптимизировать его.
window.addEventListener('scroll', throttle(() => {
const scrollTop = window.scrollY;
/* doSomething with scrollTop */
}));
Вам нужно определить функцию регулирования, чтобы обернуть исходную функцию прослушивателя событий (функция регулирования), чтобы уменьшить количество выполнений обернутой функции и позволить ей выполняться только один раз в течение фиксированного интервала времени:
function throttle(action, wait = 1000) {
let time = Date.now();
return function() {
if ((time + wait - Date.now()) < 0) {
action();
time = Date.now();
}
}
}
Чтобы сделать (дроссельную) прокрутку более плавной, вы можете сделать это, используяwindow.requestAnimationFrame()
Чтобы реализовать регулирование функции:
function throttle(action) {
let isRunning = false;
return function() {
if (isRunning) return;
isRunning = true;
window.requestAnimationFrame(() => {
action();
isRunning = false;
});
}
}
Конечно, вы можете использовать существующие колеса с открытым исходным кодом длявыполнить, подобно Lodash Такой же. вы можете посетить codepen Давайте посмотрим на приведенное выше решение с решением в Lodash._.throttle
разница между.
Неважно, какую (библиотеку с открытым исходным кодом) вы используете, важно не забывать оптимизировать обработчик прокрутки (на странице), когда это необходимо.
показать в окне
когда нужно реализовать картинкиленивая загрузкаилибесконечная прокрутка, необходимо определить, отображается ли элемент в области просмотра. Это можно обработать в прослушивателе событий, наиболее распространенным решением является использованиеlement.getBoundingClientRect()
:
window.addEventListener('scroll', () => {
const rect = elem.getBoundingClientRect();
const inViewport = rect.bottom > 0 && rect.right > 0 &&
rect.left < window.innerWidth &&
rect.top < window.innerHeight;
});
Проблема с приведенным выше кодом заключается в том, что каждый вызовgetBoundingClientRect
сработает, когдапереплавка, что сильно влияет на производительность. Вызывается в функции обработчика события (getBoundingClientRect
) особенно плох, и даже использование регулирования функций может не сильно повысить производительность. (Перекомпоновка — это когда браузер частично или полностью перерисовывает элемент, и ему необходимо пересчитать положение и форму элемента в документе.)
После 2016 года это можно сделать с помощью Intersection Observer Этот API для решения проблемы. Он позволяет отслеживать пересечение целевого элемента с его предками или окнами просмотра. Кроме того, хотя толькочастьЭлементы, появляющиеся в области просмотра, даже если это всего лишь один пиксель, могут дополнительно вызывать функцию обратного вызова:
const observer = new IntersectionObserver(callback, options);
observer.observe(element);
(нажмитездесь, чтобы увидеть свойства и методы DOM, запускающие перекомпоновку. )
Этот API широко поддерживается, но по-прежнему требуется некоторыми браузерами.polyfill. Тем не менее, это лучшее решение.
проблема границы прокрутки
Если ваш всплывающий или выпадающий список прокручивается, вы должны пониматьцепочка свитокСвязанный вопрос: когда пользователь прокручивает до конца (всплывающее или раскрывающееся меню) (а затем продолжает прокручивать), вся страница начинает прокручиваться.
(производительность прокрутки цепочки)
Когда элемент прокрутки достигает нижней части, вы можете пройти (изменить)overflow
или отмените поведение по умолчанию в обработчике событий прокрутки элемента прокрутки, чтобы исправить это.
Если вы решите использовать JavaScript (для обработки), не забывайте обрабатывать не «прокрутку (событие)», а всякий раз, когда пользователь использует колесико мыши или сенсорную панель."колесо (событие)":
function handleOverscroll(event) {
const delta = -event.deltaY;
if (delta < 0 && elem.offsetHeight - delta > elem.scrollHeight - elem.scrollTop) {
elem.scrollTop = elem.scrollHeight;
event.preventDefault();
return false;
}
if (delta > elem.scrollTop) {
elem.scrollTop = 0;
event.preventDefault();
return false;
}
return true;
}
К сожалению, это решение не очень надежно. В то же время может оказать негативное влияние на производительность (страницы).
Чрезмерная прокрутка особенно сильно влияет на мобильные устройства.Loren BrichterСоздание нового жеста «потяните, чтобы обновить» в приложении Tweetie для iOS вызвало ажиотаж в UX-сообществе: основные приложения, включая Twitter и Facebook, приняли его (тот же жест).
Когда эта функция появилась в Chrome на Android, возникла проблема: она обновляла всю страницу вместо того, чтобы загружать больше контента, что стало проблемой для разработчиков, реализующих «обновление по запросу» в своих приложениях.
CSS-пассoverscroll-behavior
Это новое свойство решает проблему. Он решает проблемы, вызванные pull-to-refresh и цепной прокруткой, контролируя поведение элементов при их прокрутке до конца, а также (в своих значениях свойств) содержит специальные значения для разных платформ:glow
В системе Applerubber band
.
Теперь проблему в GIF выше можно решить в Chrome, Opera или Firefox с помощью следующей строки кода:
.element {
overscroll-behavior: contain;
}
Честно говоря, IE и Edge реализуют (это уникально)-ms-scroll-chaining
Атрибутыдля управления прокруткой цепочки, но не во всех случаях. К счастью, согласноэта новостьБраузер Microsoft готов к внедрениюoverscroll-behavior
Это свойство есть.
После прикосновения к экрану
Прокрутка (опыт) на устройствах с сенсорным экраном — это огромная тема, и ее подробное обсуждение потребует отдельной статьи. Однако, поскольку многие разработчики игнорируют этот аспект, его необходимо здесь упомянуть.
(Жесты прокрутки настолько вездесущи и вызывают привыкание, что я придумалтакая сумасшедшая идеяЧтобы решить проблему «зависимости от прокрутки». )
Как часто окружающие двигают пальцами вверх и вниз по экрану смартфона? Часто это правильно, и вы, вероятно, делаете это, когда читаете это.
Когда вы перемещаете палец по экрану, вы ожидаете, что содержимое страницы будет перемещаться плавно и плавно.
яблокоСоздайтеимеет "инерционную" прокрутку и имеетпатент. Он быстро стал стандартом взаимодействия с пользователем, и мы к нему привыкли.
Но вы могли заметить, что хотя мобильная система будет реализовывать для вас инерционную прокрутку на странице, когдаэлемент на страницеКогда происходит прокрутка, неприятно, что она не появляется, хотя пользователь также ожидает инерционной прокрутки.
Вот решение CSS, но оно больше похоже на взлом:
.element {
-webkit-overflow-scrolling: touch;
}
Почему это взлом? Во-первых, он будет работать только в браузерах, поддерживающих префикс (webkit). Во-вторых, он работает только на устройствах с сенсорным экраном. Наконец, вы просто оставляете его в покое, если браузер его не поддерживает? Но в любом случае, это решение, можете попробовать его использовать.
На устройствах с сенсорным экраном еще одним соображением является то, как разработчикиtouchstart
а такжеtouchmove
При запуске события могут возникнуть проблемы с производительностью, что сильно влияет на работу пользователя с прокруткой.здесьВся проблема подробно описана. Проще говоря, современные браузеры знают, как сделать прокрутку плавной, но чтобы подтвердить, выполняется ли обработчик события (scroll)Event.preventDefault()
Чтобы отменить поведение по умолчанию, иногда может потребоваться 500 мс, чтобы дождаться завершения выполнения обработчика событий.
Даже пустой прослушиватель событий никогда не отменяет какое-либо поведение, учитывая, что браузер по-прежнему будет ожидатьpreventDefault
звонки, которые также могут негативно сказаться на производительности.
Чтобы сообщить браузеру, о чем именно следует беспокоиться (в обработчике событий) об отмене поведения по умолчанию, вWHATWGВ стандарте DOM существуетменее заметные особенности(может решить эту проблему). (это)Passive event listeners, поддержка браузера для него по-прежнемуПриятно. Функция прослушивателя событий вновь принимает необязательный объект в качестве параметра, сообщая браузеру, что обработчик событий никогда не отменит поведение по умолчанию при срабатывании события. (разумеется, после добавления этого параметра) вызов обработчика событияpreventDefault
больше не будет влиять.
element.addEventListener('touchstart', e => {
/* doSomething */
}, { passive: true });
Для браузеров, не поддерживающих этот параметр, также существует polyfill .это видеоВлияние этого улучшения ясно продемонстрировано.
Старая технология работает так хорошо, зачем ее менять?
В современном Интернете больше неразумно полагаться на JavaScript для достижения одинакового интерактивного эффекта в каждом браузере.«Кроссбраузерная совместимость» ушла в прошлое, и постепенно внедряются новые свойства CSS и методы DOM API. различными браузерами.Поддерживается основными браузерами.
По нашему мнению, когда в вашем проекте есть особенно крутой эффект прокрутки,прогрессивное улучшениеэто лучшая практика.
Вы должны предоставить (пользователю) весь (вы можете предоставить) базовый пользовательский опыт и постепенно улучшать работу в более продвинутых браузерах.
Используйте полифиллы, когда это необходимо, они не создают (ненужных) зависимостей, и как только (свойство, поддерживаемое полифиллом) широко поддерживается, вы можете легко удалить его.
Полгода назад, до написания этой статьи, описанные нами свойства поддерживались лишь небольшим количеством браузеров. К моменту публикации этой статьи эти свойства получили широкую поддержку.
Возможно, к настоящему моменту, когда вы пролистываете эту статью, браузеры (которые раньше не поддерживали определенные свойства) уже поддерживают это свойство, что облегчает вам программирование и уменьшает размер пакета вашего приложения.
Спасибо, что дочитали до этого места! Проверьте журнал изменений вашего браузера и активно участвуйте в обсуждениях, чтобы помочь направить веб-стандарты в правильном направлении. Желаю всем гладкого плавания и гладкого (катящегося) в будущее!