Фильтрация и сортировка элементов на javascript

Всем привет, сегодня поговорим о том, какие способы сортировки и фильтрации элементов (например, товары в интернет магазине) существуют. Сильные и слабые стороны различных реализаций.
В этой статье мы напишем на javascript фильтр товаров и их сортировку без перезагрузки страницы.
Так же я покажу некоторые подводные камни, возникающие при организации фильтрации элементов.
Содержание статьи:
Давайте определимся с некоторыми терминами:
Фильтрация - это выборка каких-либо элементов из базы данных по определенным параметрам. При этом элементы не подходящие под заданные параметры будут скрыты.
Сортировка - это расположение элементов на странице в определенном порядке, например, по возрастанию цены. В этом случае, в начале списка будут показаны самые дешевые товары, а уже ниже будут товары подороже.
Когда-то давным давно
Когда-то давным давно, когда javascript использовался только для анимаций и слайдеров, все манипуляции с данными производили на стороне сервера.
Например, для того, чтобы отфильтровать товары человек заполнял фильтр, который представлял из себя форму с несколькими полями и нажимал кнопку “Показать”. Далее страница перезагружалась и мы видели товары, попадающие в рамки фильтра.
Принцип работы фильтра в этом случае заключался в следующем:
- При нажатии на кнопку “Показать” на сервер уходил POST или GET запрос, содержащий критерии фильтра.
- Серверный скрипт, обрабатывающий этот запрос, анализировал его и отправлял запрос в базу данных.
- Получив ответ от базы данных, скрипт отправлял пользователя на специальную страницу или перезагружал существующую, на которой и выводился результат поиска.
Примерно по такому же принципу происходила и сортировка товаров, например, по возрастанию или убыванию цены. Только нас не перекидывали на новую страницу, а перезагружали существующую. При этом показывая все товары просто в определенном порядке.
У такого подхода есть большой минус - для каждой фильтрации или сортировки нужно было перезагружать страницу. А при медленном интернете каждая новая перезагрузка вызывает у пользователя только раздражение.
Фильтр товаров на javascript
С развитием веб технологий был придуман способ организации фильтра товаров на javascript c помощью Ajax.
Внешне фильтр все так же выглядит в виде формы с несколькими полями и кнопкой применения фильтра. Немного изменилась лишь логика его работы:
- Пользователь заполняет поля фильтра и нажимает кнопку “Применить”.
- Скрипт, написанный уже на javascript срабатывает по событию нажатия кнопки и отправляет Ajax запрос на сервер, показывая при этом индикатор загрузки (спинер).
- Серверный скрипт обрабатывает запрос и на его основе делает запрос к базе данных с товарами.
- Далее сервер отправляет ответ, в котором содержится список товаров, попадающих в рамки фильтра.
- Javascript скрывает спиннер и на основе ответа от сервера показывает полученные товары.
Используя этот способ нет необходимости перезагружать страницу. С сервера приходят данные и на сайте мы перерисовываем только список товаров. Это не только экономит трафик, но и ускоряет работу сайта.
Можно обойтись и без Ajax. В этом случае все товары должны быть загружены на страницу и фильтрация производится только среди них. Логика получается совсем простая - товары не подходящие под фильтр мы просто скрываем. Единственное, у такого подхода могут быть проблемы с версткой:
See the Pen Filter red blocks by Alexandr (@login2030) on CodePen.
В данном примере отфильтруйте элементы, оставив только красные блоки. Как видите, верстка, в этом случае, “плывет”. Это происходит из-за того, что блоки перестроились лишь визуально, а в DOM дереве их положение не изменилось.
Решений у этой проблемы несколько:
- Перестраивать DOM дерево, чтобы блоки подходящие под фильтр перемещались в начало DOM дерева.
- Воспользоваться скриптом, который организует сетку для товаров самостоятельно.
- Переписать верстку на Flexbox.
Давайте разберем все способы по порядку
Перестраивание DOM дерева
В интернете можно найти множество способов, как отсортировать элементы в DOM дереве. Я же предпочитаю пользоваться миниатюрным jQuery плагином sortElements
See the Pen Sort DOM for filter red blocks by Alexandr (@login2030) on CodePen.
Скрипт для организации сетки
Таких скриптов я знаю два - Masonry и Isotope. Эти скрипты очень актуальны в том случае, если фильтруемые блоки имеют разную высоту. Вот пример использования Masonry:
See the Pen Masonry filter red blocks by Alexandr (@login2030) on CodePen.
Обратите внимание на 2 новых блока внутри row
:
|
|
grid-sizer необходимо задать такую же ширину, как и нашим блокам item
.
gutter-sizer необходимо задать ширину, равную расстоянию между нашими блоками, т.е. 25px
.
А при нажатии на кнопку фильтрации, Masonry необходимо обновить:
|
|
Переписать верстку на Flexbox
See the Pen Flexbox filter red blocks by Alexandr (@login2030) on CodePen.
Как Вы можете заметить, верстка при фильтрации не ломается. Но если в нижнем ряду будет 2 элемента, то они будут поровну делить все пространство родителя. А если останется только один элемент, то он разместиться в центре родительского блока.
Сортировка товаров на javascript
Как мы уже знаем из определения, сортировка - это расположение элементов в определенном порядке. В нашем случае сортировать мы будем разноцветные товары. Результатом нашей сортировки будет перемещение всех красных товаров в начало списка. При этом никакие блоки мы теперь скрывать не будем
Сортировка товаров возможна как на стороне сервера, так и на стороне клиента. В данном случае мы рассмотрим сортировку на клиенте, т.е. на javascript.
- Сортировка товаров по цене, с помощью изменения DOM дерева:
See the Pen Sort elements by Alexandr (@login2030) on CodePen.
Как видно из примера, мы воспользовались тем же плагином sortElements для организации сортировки.
- Сортировка товаров по цене с помощью Isotope:
See the Pen Isotope sort elements by Alexandr (@login2030) on CodePen.
Как видите, сортировка с помощью Isotope производится с приятной анимацией.
Давайте разберем этот пример более детально. Верстка практически не отличается от остальных примеров, за исключением того, что цена теперь помещена в специальный тег p
с классом number
:
|
|
Стили перекочевали полностью из примера с Masonry, единственное, что добавились правила для нашего параграфа с ценой:
|
|
И наконец сам скрипт:
|
|
В Isotope masonry является одним из вариантов лейоута, поэтому указываем его в настройке
|
|
Далее идет настройка:
|
|
В которой мы указываем скрипту, по какому значению будем сортировать список товаров. Сортировать мы будем по тому, что находится внутри класса number
, а так же, мы приведем это к числу с помощью parseInt
.
Далее идут обработчики кликов на кнопки. Стоит отметить, что поле sortAscending
отвечает непосредственно за порядок сортировки. По умолчанию оно установлено в true
и сортирует в порядке 1,2,3,4,5, а если поставить его в false
, то сортировка будет в обратном направлении. Только не забудьте указать параметр sortAscending в обоих случаях, так как автоматически он не переключается.
Более подробную информацию Вы найдете в [ Документации ]
Заключение
В этой статье я рассказал каким образом можно фильтровать и сортировать элементы на стороне клиента.
Если Вам понравилась статья, то можете поделиться ей в социальных сетях.
Если что-то не поняли или есть какие-то вопросы, то пишите комментарии, я постараюсь помочь.
Важно помнить, что все примеры в статье являются демонстрационными и не претендуют быть самыми лучшими =)