Обзор
Плагин jQuery.Snapper
предназначен для управления
размещением и перемещением панелей на странице. Основные отличия
от аналогичных плагинов:
- Не привязан ни к каким мекетам верстки. Использует произвольную разметку как самой страницы, так и перемещаемой панели.
- Предназначен для использования как на десктопах, так и мобильных устройствах. Эффекты инерционности и анимации при переносе элементов. Поддерживает режимы управления мышью, стилусом и пальцем.
- Позволяет управлять удалением элементов со страницы, а также захватом при выходе за пределы страницы.
- При необходимости сохраняет размещение панелей на странице в кэше браузера.
Загрузить jQuery.Snapper
Описание | Рабочая версия | Версия для отладки |
---|---|---|
Управление размещением и перемещением панелей | jquery.snapper.min.js | jquery.snapper.js |
Сохранение размещения панелей в кэше браузера | jquery.snapper.storage.min.js | jquery.snapper.storage.js |
Ввода пальцами для IE10 с поддержкой скроллинга | jquery.mspointer.min.js | jquery.mspointer.js |
Как это работает
На странице размещается несколько контейнеров, содержаших перемещаемые панели. Плагин устанавливается на все контейнеры. Захват панели производится долгим нажатием или кликом для режима стилуса. После отпускания с учетом инерции рассчитывается точка приземления, определяется контейнер, готовый принять понель и место вставки. Затем выполняется перемещение понели в DOM-модели, браузер пересчитывает новые координаты элементов и размеры исходного и нового контейнера, после чего производится демонстрация мультфильма по перемещению панели и сдвигу других панелей из исходного положения в новое.
Зависимости
Единственная обязательная зависимость - jQuery
.
На мобильных устройства для плавной анимации опционально можно добавить
jQuery.Transit
- замена
animate
на transition
.
При необходимости изменения функции инерционной анимации можно добавить
библиотеку jQuery.Easing
.
Подключение плагина
Для использования необходимо включить библиотеку jQuery.Snapper
на
страницу, содержащую контейнеры. Привязка плагина к контейнеру производится путем
маркировки атрибутом data-toggle="snapper"
или через вызов метода инициализации плагина $('.container').snapper()
.
<!-- Библиотека с плагином -->
<script src="js/libs/jquery.snapper.min.js"></script>
...
<!-- Контейнер с плагином -->
<div class="container" data-toggle="snapper">
<div class="panel">...</div>
<div class="panel">...</div>
<div class="panel">...</div>
</div>
Несколько контейнеров
Контейнеров на странице может быть несколько и разного размера. По умолчанию они все готовы захватывать панели других контейниров на своей территории.
<!-- Верхний контейнер -->
<div class="container top" data-toggle="snapper">
<div class="panel">...</div>
<div class="panel">...</div>
</div>
<!-- Левый контейнер -->
<div class="container left" data-toggle="snapper">
<div class="panel">...</div>
<div class="panel">...</div>
</div>
<!-- Правый контейнер -->
<div class="container right" data-toggle="snapper">
<div class="panel">...</div>
<div class="panel">...</div>
</div>
Пример 1. Несколько контейнеров
Запрет выхода из контейнера
По умолчанию панель, брошенная за переделы контейнера будет удалена
из DOM-модели или захвачен другим контейнером. Для запрета удаления
панелей из контейнера установите data-out="cancel"
.
Перемещение панелей становится возможно только внутри контейнера. Такой контейнер также
не будет захватывать панели других контейнеров.
Панели можно переставлять только внутри этого контейнера
Панели можно удалить или перенести в другой контейнер
<!-- Перемещение панелей только внутри контейнера -->
<div class="container" data-toggle="snapper" data-out="cancel">
<div class="panel">...</div>
<div class="panel">...</div>
</div>
<!-- Перемещение и удалений панелей из контейнера -->
<div class="container" data-toggle="snapper" data-out="remove">
<div class="panel">...</div>
<div class="panel">...</div>
</div>
Обмен панелями
Если все же необходимо чтобы панели могли переходить на другой контейнер при этом
количество панелей на каждом контейнере оставалось неизменными применяется.
атрибут data-out="swap"
При переносе контейнеры обмениваются панелями
<!-- Перемещение и удалений панелей из контейнера -->
<div class="container" data-toggle="snapper" data-out="swap">
<div class="panel">...</div>
<div class="panel">...</div>
<div class="panel">...</div>
</div>
<!-- Перемещение панелей только внутри контейнера -->
<div class="container" data-toggle="snapper" data-out="swap">
<div class="panel">...</div>
<div class="panel">...</div>
<div class="panel">...</div>
</div>
Ловушки для панелей
При сложной верстке может потребоваться размешение панелей в различных местах
странице по разными контейнерам. При этом часто возникает необходимость предотварить
возможность выхода элемента за пределы экрана и удаление. С этой целью на одном или нескольких
контейнерах можно включить ловушки, установив атрибут data-catch="..."
.
Атрибут может принимать одно или несколько значений из набора top right bottom left
.
Указание направления отменяет проверку соответствующей координаты контейнера для
определения территории захвата.
Если указать сразу все четыре направления - контейнер будет ловить все панели, поэтому такой контейнер должен быть последним при создании в DOM-модели или к нему последнему должен быть применен плагин.
Чтобы ловушка срабатывала гарантированно, важно установить на нее фиксированную (или максимальную)
для своего основного направления ширину/высоту. В приведенном примере панели улетят,
если будут брошены выше окна примера. Поэтому эти ловушки не ловят панели удаляемые из верхних
примеров. Но если в левый и правый контейнеры добавить значение top
, то данный пример
станет полными замыканием для всей страницы и не позволит уйти с нее не одной панели.
<!-- Ловушка слева -->
<div class="container left" data-toggle="snapper" data-catch="left">
<div class="panel">...</div>
<div class="panel">...</div>
</div>
<!-- Ловушка справа -->
<div class="container right" data-toggle="snapper" data-catch="right">
<div class="panel">...</div>
<div class="panel">...</div>
</div>
<!-- Ловушка снизу и по сторонам для надежности -->
<div class="container bottom" data-toggle="snapper" data-catch="bottom left right">
</div>
Обработка событий
Плагин в процессе перемещения панели вызывает на контейнере следующие события:
- Отрыв панели от контейнера и начало перетаскивания
drag
- Бросание панели в позиции с учетом инерции движения
drop
- Завершение захвата панели (создает контейнер приемник)
snap
- Завершение перемещения/удаления панели (создает контейнер источник)
done
<script>
$(function() {
<!-- Обработка события завершения перемещения -->
$(document).on('done.snapper', '.container', function() {
$.waypoints('refresh');
});
$('.panel').css('opacity', 0);
$('.panel').waypoint(function(direction) {
$(this).animate({opacity: direction === 'down' ? 1 : 0}, 400);
}, {offset: '90%'});
</script>
Сохранение состояний
Для добавления сохранения размещения панелий на странице достаточно включить
добавить библиотеку jQuery.Snapper.Storage
.
Идентификация контейнеров и панелей производится по id
элемента.
Если не задано присваивается автоматически в порядке размещения на странице.
С точки зрения будущих изменений/обновлений страницы рекомендую добавлять id
на каждый элемент.
Если в дальнейшем изменяется начальный состав панелей в контейнере, например добавляется
новая панель, чтобы корректно обновить страницу пользователя достаточно включить
в идентификатор id
номер версии контейнера. Существующие перемещенные элементы
в этом случае у пользователя займут свои места, а новые элементы будут отражены
в контейнера новой версии.
<!-- Библиотека с плагином -->
<script src="js/libs/jquery.snapper.min.js"></script>
<!-- Библиотека сохранения состояний -->
<script src="js/libs/jquery.snapper.storage.min.js"></script>
...
<!-- Размещение панелей сохраняется в кэше браузера -->
<div id="block_1" class="container" data-toggle="snapper">
<div id="item_1" class="panel">...</div>
<div id="item_2" class="panel">...</div>
<div id="item_3" class="panel">...</div>
</div>
Пример 3. Сохранение состояний
Стилевое оформление
Панель в процессе перемещения привязана к document.body
. Стиль можно задать через привязку к родителю.
Таким образом, например, можно задать эффект "отлипания" панели от контейнера.
<!-- Панель приподнимается над контейнером -->
body > .panel {
-moz-box-shadow: 0 0 15px #555;
-webkit-box-shadow: 0 0 15px #555;
box-shadow: 0 0 15px #555;
border: outset 1px #f0f0f0;
transition: border, box-shadow ease-in 200ms;
-webkit-transition: border, -webkit-box-shadow ease-in 200ms;
-moz-transition: border, -moz-box-shadow ease-in 200ms;
}
Управление пальцами в IE10
Для управления размещением панелей пальцами в IE10 требуется указать
параметр -ms-touch-action: none
. Но в этом случае исчезает
возможность пальцем осуществлять плавный скроллинг. В FF и WebKit
блокировка системного скроллинга может быть осуществлена непосредственно
из обработчика событий. Напротив в IE10 параметр -ms-touch-action: none
начинает работать только после окончания касания экрана.
Для совмещения функции системного скроллинга в IE10 и работы плагина
используется библиотека jQuery.MSPointer
,
которая для IE10 подменяет мышиные события MouseEvent на события MSPointerEvent,
что позволяет различать ввод мышью/пальцами/пером. В этом случае особенностью работы
пальцами/пером в IE10 при сохранении скроллинга становиться необходимость повторного касания
экрана для перемещения панели при временно отключенном системном скроллинге.
Если приложении не исползует системный скроллинг пальцам в IE10 включать эту библиотеку не рекомендуется.
<!-- Подмена мышиных событий в IE10 -->
<script src="js/libs/jquery.mspointer.min.js"></script>
<!-- Библиотека с плагином -->
<script src="js/libs/jquery.snapper.min.js"></script>
...
<!-- Для IE10 здесь будет работать системный скроллинг и перемещение панелей пальцами -->
<div id="block_1" class="container" data-toggle="snapper">
<div id="item_1" class="panel">...</div>
<div id="item_2" class="panel">...</div>
<div id="item_3" class="panel">...</div>
</div>