Порада: вручну сортований списки з допомогою Flexbox і jQuery

20

Від автора: у цій статті ми докладно розберемо, як створити простий jQuery плагін, який буде сортувати елементи за значенням користувальницьких data-атрибутів.

Цікаві можуть відразу побачити кінцевий результат у CodePen демо:

Зауваження: стаття передбачає наявність базового розуміння flexbox, а також уміння розробляти плагіни на jQuery. Якщо дані теми вам не знайомі, перейдіть за відповідним посиланням.

Питання доступності

Для створення плагіна ми скористаємося перевагами flexbox. За замовчуванням флекс осередку шикуються у вихідному порядку. За допомогою властивості order ми можемо змінити цей порядок всередині флекс контейнера. Елементи з меншим значенням order з’являються раніше. Дивіться приклад нижче:

Якщо у декількох елементів задано одне значення order, їх черговість визначається вихідним порядком.

Властивість order дозволяє легко сортувати елементи, однак воно несе в собі певні обмеження щодо доступності: дана властивість розриває вихідний порядок і візуальний. Щоб краще зрозуміти суть проблеми, прочитайте цю статтю (особливо розділ Source Order vs. Visual Order).

Перш ніж перейти до створення плагіна вам важливо зрозуміти, що він не буде доступним.

Розмітка

Для початку пропишіть ненумерованний список з 12 елементів:

  • Box1

    13M
    670€

Зверніть увагу, що в кожному елементі списку є блок .details, в якому зберігається інформація про відповідному елементі списку. Трохи нижче ми також додамо користувальницькі HTML-атрибути, в яких будемо зберігати інформацію.

Зауваження: елемент .details необов’язковий. Ми використовуємо його лише для того, щоб краще зрозуміти принцип сортування цільових елементів.

Далі ми задаємо атрибути, за якими буде проводитися сортування. У нас це атрибути price і length. Ми використовуємо їх імена користувача атрибутах (data-price і data length) елементів списку. Значення цих атрибутів будуть збігатися з текстовими значеннями (тільки цифри) елементів .length і .price, які розташовані в блоці .details.

Наприклад, атрибути для першого елемента списку:

  • Box1

    13M
    670€
  • Тепер необхідно вказати елементи, з допомогою яких буде здійснюватися сортування. Для цього ми візьмемо тег select:

    Sort By
    Price Ascending
    Price Descending
    Length Ascending
    Length Descending

    Як ви могли помітити, у всіх тегів
    за винятком першого є атрибут data-sort. Значення атрибута задано в наступному форматі:

    У нас є атрибут зі значенням, за яким необхідно зробити сортування. Після значення стоїть двокрапка, і слід індикатор «asc» або «desc».

    Стилі CSS

    Наша розмітка готова, тепер давайте додамо базові стилі на нашу сторінку. Нам необхідно перетворити ненумерованний список флекс контейнер і привласнити елементам списку ширину width: 25%. Відповідні CSS стилі:

    .boxes {
    display: flex;
    flex-wrap: wrap;
    }
    .boxes li {
    width: 25%;
    }

    Створення плагіна

    Назвемо наш плагін numericFlexboxSorting. Перш ніж показати процес створення, давайте почнемо з кінця, і пояснимо, як ініціалізувати плагін.

    Ініціалізація плагіна

    У двох словах, плагін ініціалізується наступним чином:

    $(«ваш-тег-select»).numericFlexboxSorting();

    В нашому випадку так:

    $(«.b-select»).numericFlexboxSorting();

    За замовчуванням плагін буде сортувати елементи з класом .boxes li. Це можна змінити, переписавши значення властивості elToSort.

    $(«.b-select»).numericFlexboxSorting({
    elToSort: «елементи-для-сортування»
    });

    Покроковий розбір

    А тепер ми можемо перейти до опису процесу розробки!

    По-перше, необхідно розширити прототип об’єкта jQuery ($.fn), додавши до нього метод numericFlexboxSorting:

    $.fn.numericFlexboxSorting = function() {
    const $select = this;
    // код тут
    return $select;
    };

    Ключове слово this у цьому методі відсилає нас до тегу select. Як тільки ми створимо плагін, нам потрібно буде повертати цей тег. Якщо цього не робити, зчіпка методів не спрацює.

    Розберемо приклад коду:

    $(«.b-select»).numericFlexboxSorting().css(«background», «red»);

    Якщо ми не повернемо цільової елемент, метод css не зробить рівним рахунком нічого.

    Ми вже говорили, що плагін за замовчуванням буде сортувати елементи з класом .boxes li. Нам потрібна можливість змінювати цю поведінку, якщо з’явиться така необхідність. Для цього ми скористаємося jQuery методом extend:

    $.fn.numericFlexboxSorting = function(options) {
    const settings = $.extend({
    elToSort: «.boxes li»
    }, options);
    // код тут
    };

    Плагін буде сортувати числа за зростанням і спаданням. Для цього необхідно створити відповідні змінні, які будуть використовуватися потім:

    $.fn.numericFlexboxSorting = function(options) {
    const ascOrder = (a, b) => a — b;
    const descOrder = (a, b) => b — a;
    // код тут
    };

    Як тільки користувач вибере опцію з випадаючого списку (окрім першої), ми повинні витягнути і оцінити її значення. Для цього нам знадобиться подія change:

    $.fn.numericFlexboxSorting = function(options) {
    const $select = this;
    $select.on(«change», () => {
    const selectedOption = $select.find(«option:selected»).attr(«data-sort»);
    sortColumns(settings.elToSort, selectedOption);
    });
    // код тут
    };

    Всередині обробника події ми:

    витягуємо значення атрибута data-sort для обраної опції (наприклад, price:asc);

    викликаємо функцію sortColumns.

    Функція sortColumns приймає два параметри:

    елементи сортування;

    значення атрибута data-sort для обраної опції.

    Сама функція:

    function sortColumns(el, opt) {
    const attr = «data-» + opt.split(«:»)[0];
    const sortMethod = (opt.includes(«asc»)) ? ascOrder : descOrder;
    const sign = (opt.includes(«asc»)) ? «» : «-«;
    // 1
    const sortArray = $(el).map((i, el) => $(el).attr(attr)).sort(sortMethod);
    // 2
    for (let i = 0; i < sortArray.length; i++) {
    $(el).filter(`[${attr}=»${sortArray}»]`).css(«order», sign + sortArray);
    }
    }

    Розберемо код функції:

    Залежно від атрибута сортування (наприклад, price або length) ми отримуємо значення відповідного data-* атрибута для кожного цільового елемента і зберігаємо отримані значення в масиві. Крім того, в залежності від того, як користувач хоче сортувати цільові елементи, ми сортуємо масив за зростанням або спаданням.

    Проходимся в циклі по масиву, знаходимо відповідні елементи і присвоюємо їм властивість order зі значенням (позитивним або негативним), яке визначається значенням відповідного data-* attribute. Наприклад, якщо користувач вибере price:asc, то елемент з data-price: 315 отримає властивість order: 315.

    Совет: вручную сортируемые списки с помощью Flexbox и jQuery

    Якщо ж користувач вибере price:desc, то елемент отримає властивість order: -315.

    Совет: вручную сортируемые списки с помощью Flexbox и jQuery

    І нарешті, щоб уникнути конфліктів з іншими бібліотеками, що використовують змінну $, ми обернем наш код у моментально виконувану функцію:

    (function($) {
    $.fn.numericFlexboxSorting = function(options) {
    // код тут
    };
    })(jQuery);

    Наш плагін готовий. Подивитися його в живу можна в CodePen демо нижче:

    Обмеження в плагіні

    Пора згадати, що в нашому плагіні є одне велике обмеження: він не доступний. Щоб перевірити це, виберіть з випадаючого списку та натисніть на клавіатурі (натисніть на блок і натисніть клавішу Tab для переходу між посиланнями. Зверніть увагу, що елементи отримують фокус з DOM порядку, а не CSS.

    Совет: вручную сортируемые списки с помощью Flexbox и jQuery

    Також наш плагін забезпечує лише базовий функціонал, що обмежує його роботу тільки певними умовами. Наприклад, рядок зі значенням атрибута повинна містити числове значення. Це значення визначає order (очікує число) для цільових елементів.

    В мережі повно надійних і потужних бібліотек для сортування та фільтрування елементів: Isotope, MixItUp.

    Підтримка в браузерах

    В плагіні використовується flexbox, тобто його підтримка залежить від підтримки flexbox в браузерах. На щастя, сьогодні у flexbox чудова підтримка.

    Дані про підтримку flexbox в основних браузерах можна знайти на Can I Use flexbox?

    Наступні кроки

    Любите складності і хочете розширити функціонал плагіна? Тоді ви можете:

    додати підтримку випадкової сортування;

    дати користувачеві вибір на кнопці сортування (тег select, кілька кнопок button або елемент іншого типу). Для цього вам знадобляться додаткові налаштування:

    $(«.b-select»).numericFlexboxSorting({
    elToSort: «the elements-you-want-to-sort»,
    controls: {
    select: true, // запускає подія change
    button: false // запускає подія click
    }
    });

    Висновок

    У цій статті ми пройшли через весь процес створення плагіна на jQuery. Плагін використовує можливості flexbox для сортування елементів за значенням їх data-атрибутів.

    А що ви думаєте? Використали б ви таке в майбутньому? Чи намагалися ви якось по-іншому поєднати JS і flexbox? Пишіть в коментарях.