Waypoints — это библиотека для управления событиями при прокрутке
страницы, позволяющая запускать функции при достижении определённых
элементов. В контексте модальных окон возникает ряд особенностей, так
как стандартная логика отслеживания позиции элемента привязана к видимой
области окна браузера (window). В модальных окнах ситуация
меняется, так как контент находится внутри собственного прокручиваемого
контейнера. Для корректной работы необходимо учитывать контейнер
модального окна как отдельную область для Waypoints.
var waypoint = new Waypoint({
element: document.querySelector('.modal-content .target'),
handler: function(direction) {
console.log('Элемент достигнут: ' + direction);
},
context: document.querySelector('.modal-content')
});
Ключевой момент: свойство context
указывает, что Waypoint должен отслеживать прокрутку не всего
окна, а указанного контейнера .modal-content. Без
этого Waypoint не сработает внутри модального окна, если страница в
целом не прокручивается.
Waypoints позволяет настраивать смещение относительно начала
контейнера через параметр offset. В модальных окнах это
особенно важно, так как видимая область обычно ограничена, и стандартное
значение offset: '0' может срабатывать слишком рано или
слишком поздно. Можно использовать как пиксели, так и процент высоты
контейнера:
var waypoint = new Waypoint({
element: document.querySelector('.modal-content .target'),
handler: function(direction) {
console.log('Элемент достигнут на 50% высоты контейнера');
},
context: document.querySelector('.modal-content'),
offset: '50%'
});
Примечание: Значение '50%'
рассчитывается относительно видимой области прокручиваемого контейнера,
а не всего документа.
В модальных окнах часто содержимое генерируется динамически или имеет изменяемую высоту. В таких случаях Waypoints необходимо пересчитывать, чтобы корректно определять позиции элементов.
var waypoint = new Waypoint({
element: document.querySelector('.modal-content .dynamic-target'),
handler: function(direction) {
console.log('Динамический элемент достигнут');
},
context: document.querySelector('.modal-content')
});
// После изменения контента
waypoint.context.refresh();
Для групп элементов можно использовать
Waypoint.refreshAll(), чтобы обновить все точки на странице
или внутри модального контейнера:
Waypoint.refreshAll();
Это предотвращает некорректное срабатывание точек при добавлении новых элементов или изменении размеров контейнера.
Если на странице одновременно присутствуют несколько модальных окон с
прокручиваемым содержимым, для каждого контейнера необходимо создавать
отдельные Waypoints с индивидуальным context:
var modal1Waypoint = new Waypoint({
element: document.querySelector('#modal1 .target'),
handler: function(direction) {
console.log('Modal 1, элемент достигнут');
},
context: document.querySelector('#modal1 .modal-content')
});
var modal2Waypoint = new Waypoint({
element: document.querySelector('#modal2 .target'),
handler: function(direction) {
console.log('Modal 2, элемент достигнут');
},
context: document.querySelector('#modal2 .modal-content')
});
Совет по производительности: создавать Waypoints
только при открытии модального окна и уничтожать их при закрытии через
метод destroy(). Это снижает нагрузку на браузер и
предотвращает накопление неиспользуемых обработчиков:
modal1Waypoint.destroy();
Waypoints передаёт параметр direction в обработчик,
который может быть 'down' или 'up'. Это
позволяет запускать разные действия в зависимости от направления
прокрутки внутри модального окна:
var waypoint = new Waypoint({
element: document.querySelector('.modal-content .target'),
handler: function(direction) {
if (direction === 'down') {
console.log('Прокрутка вниз');
} else {
console.log('Прокрутка вверх');
}
},
context: document.querySelector('.modal-content')
});
В модальных окнах с небольшим контентом часто удобно комбинировать
offset и direction, чтобы анимации или
подсветка элементов срабатывали именно в нужный момент.
При работе с Waypoints в модальных окнах часто применяют анимации появления элементов. Чтобы избежать преждевременного срабатывания:
opacity: 0; transform: translateY(50px);) и запускать
анимацию при срабатывании Waypoint.offset с учётом размеров контейнера и
высоты анимации.handler для добавления CSS-классов,
управляющих анимацией:var waypoint = new Waypoint({
element: document.querySelector('.modal-content .animated'),
handler: function(direction) {
this.element.classList.add('fade-in');
},
context: document.querySelector('.modal-content'),
offset: '75%'
});
На мобильных устройствах прокручиваемые модальные окна могут вести себя иначе из-за аппаратного ускорения и различных методов прокрутки. Рекомендуется:
offset, чтобы компенсировать особенности
touch-прокрутки.refresh() после изменения размеров окна
(resize) или ориентации экрана
(orientationchange).Waypoints хорошо интегрируется с библиотеками для модальных окон,
например, с Bootstrap Modal. В таких случаях создание
Waypoints лучше привязывать к событию shown.bs.modal, чтобы
гарантировать, что контент полностью доступен для измерений:
$('#myModal').on('shown.bs.modal', function () {
new Waypoint({
element: this.querySelector('.target'),
handler: function() {
console.log('Элемент в модальном окне достигнут');
},
context: this.querySelector('.modal-content')
});
});
Такой подход предотвращает ошибки, связанные с попыткой измерить элементы до их полной отрисовки в DOM.