Alpine.js - це новий легкий фреймворк JavaScript, який використовує підхід додавання поведінки безпосередньо у вашій HTML-розмітці. Згідно з документацією;
Alpine.js пропонує вам реактивний і декларативний характер великих фреймворків, таких як Vue або React, за набагато нижчою вартістю. Ви можете зберегти свій DOM і посипати поведінку так, як вважаєте за потрібне.
Після включення коду – я використовую метод npm – ви можете посипати потрібну поведінку. Вони забезпечують акуратність приклад для вкладок;
<div x-data="{ tab: 'foo' }">
<button class="button" :class="{ 'button--active': tab === 'foo' }" x-on:click="tab = 'foo'">Foo</button>
<button class="button" :class="{ 'button--active': tab === 'bar' }" x-on:click="tab = 'bar'">Bar</button>
<div x-show="tab === 'foo'">Tab Foo</div>
<div x-show="tab === 'bar'">Tab Bar</div>
</div>
Якщо ви розумієте базові HTML та JavaScript, ви, сподіваємось, можете зрозуміти, що відбувається досить легко. Події кліків додаються до <button>
елементів за допомогою атрибутаx-on:click
. Атрибут x-show
- це обчислення, який елемент показати. І :class
використовується для додавання «активного» класу до кнопки.
Набір елементів стає компонентом за допомогою атрибутаx-data
, який у прикладі вище за замовчуванням використовує видиму вкладку.
Створення списку
перетягування, яке мені нещодавно знадобилося для створення інтерфейсу перетягування. Зазвичай я тягнувся б до попередньо створеного рішення, дослідження які пакети доступні і вирішують, що використовувати. Це було зроблено для того, щоб уникнути кросбраузерних проблем і заново винайти колесо.
Однак підтримка JavaScript значно покращилася з роками, і браузери додали Вбудована підтримка подій перетягування. Це відносно невелика складова, тому не мало особливого сенсу використовувати велику бібліотеку для досягнення того, що було потрібно.
Його створення
Першим кроком у створенні будь-якого подібного компонента є визначення HTML, який ми хочемо використовувати. Я використовував методологію BEM, щоб допомогти угоді про іменування.
Нам знадобляться два списки, кожен зі своїм заголовком, контейнером і дільником.
<div class="drag-and-drop">
<div class="drag-and-drop__container drag-and-drop__container--from">
<h3 class="drag-and-drop__title">From</h3>
<ul class="drag-and-drop__items">
<li class="drag-and-drop__item"></li>
</ul>
</div>
<div class="drag-and-drop__divider">⇄</div>
<div class="drag-and-drop__container drag-and-drop__container--to">
<h3 class="drag-and-drop__title">To</h3>
<ul class="drag-and-drop__items">
<li class="drag-and-drop__item"></li>
</ul>
</div>
</div>
Створіть альпійський.js компонент
Тепер нам потрібно почати додавати наш Alpine.js. Почніть з додавання атрибута, x-data
щоб налаштувати нашу нову область компонентів.
<div class="drag-and-drop" x-data>
...
</div>
Далі нам потрібно позначити, які елементи можна перетягувати. Ми хочемо, щоб його <li>
можна було перетягнути, тому додаємо до нього атрибут.
<li class="drag-and-drop__item" draggable="true"></li>
Прив'язка подій
Нам потрібно визначити, куди можна скинути перетягується елемент. Нам потрібно прив'язати подію до обох <ul>
елементів. Тут ми можемо використовувати атрибут Alpine.jsx-on
.
<ul class="drag-and-drop__items" x-on:drop="">
...
</ul>
Є й інші події, які ми можемо слухати, щоб додати доступності до взаємодії з користувачем.
<ul class="drag-and-drop__items"
x-on:drop=""
x-on:dragover.prevent=""
x-on:dragleave.prevent="">
...
</ul>
Налаштування даних і перемикання
На даний момент це лише оболонки подій і насправді нічого не роблять. Щоб зробити їх корисними, ми можемо почати маніпулювати дані про компонент. Для початку нам потрібно налаштувати, про які властивості компонента повинен піклуватися. Ми хочемо знати коли елемент додається або видаляється. Ми можемо налаштувати ці за замовчуванням так;
<div class="drag-and-drop" x-data="{ adding: false, removing: false }">
...
</div>
Тепер ми можемо маніпулювати цими атрибутами всередині наших подій. Для нашого списку "Кому" ми хочемо знати Коли ми додаємо новий елемент, ми оновлюємо adding
властивість. Аналогічно, ми б оновили removing
нерухомість за списком "Від". Ось як зараз виглядає список "Кому".
<ul class="drag-and-drop__items"
x-on:drop=""
x-on:dragover.prevent="adding = true"
x-on:dragleave.prevent="adding = false">
...
</ul>
Ми змінили деякі значення, але немає видимих відгуків інтерфейсу користувача, коли це відбувається. Ми можемо зробити це, змінивши стилі, шляхом зміни класів у списку. Коли властивість adding
true
є, ми можемо додати a новий клас з використанням :class
атрибута. Цей клас видаляється, коли властивість adding
є false
.
<ul class="drag-and-drop__items"
:class="{ 'drag-and-drop__items--adding': adding }"
x-on:drop=""
x-on:dragover.prevent="adding = true"
x-on:dragleave.prevent="adding = false">
...
</ul>
Ми будемо використовувати той самий синтаксис при видаленні елементів, перемикаючи властивість removing
і змінюючи клас. Я використовував класdrag-and-drop__items--removing
, але ми могли б використовувати однакову назву класу для обох списків.
Ми можемо застосувати ту саму ідею до стилізації предмета, який ми хочемо перетягнути. На даний момент у нас є тільки draggable
застосований атрибут. Давайте встановимо кожен елемент як компонент, зв'яжемо деякі події та оновимо клас.
<li
class="drag-and-drop__item"
:class="{ 'drag-and-drop__item--dragging': dragging }"
draggable="true"
x-data="{ dragging: false }"
x-on:dragstart.self="dragging = true"
x-on:dragend="dragging = false">
...
</li>
Зверніть увагу, .self
що ми додали модифікатор до прив'язки події. У документації сказано;
Додавання
.self
до слухача події запустить обробника лише в тому випадку, якщо це$event.target
сам елемент.
Обробляйте перетягування
Поки що ми зв'язали кілька подій і використали ці події, щоб забезпечити доступність користувальницького інтерфейсу, оновивши перетягування стилю елемента та показ місця, куди елемент може бути скинутий. Далі нам потрібно фактично перемістити елемент.
Нам потрібно використовувати dragstart
подію для оновлення об'єктаdataTransfer
. Цей об'єкт зберігає інформацію який доступний для проведення drop
заходу. Коли ми рухаємо наш предмет, ми встановлюємо effectAllowed
власність на move
. По-друге, нам потрібно додати інформацію про нашу стихію до заходу. Оскільки кожен предмет має , id
ми можемо використовувати що як орієнтир.
x-on:dragstart.self="
dragging = true;
event.dataTransfer.effectAllowed = 'move';
event.dataTransfer.setData('text/plain', event.target.id);
"
Тепер подія, яку ми прив'язали до цільового контейнера, drop
має доступ до цієї інформації. Замість того, щоб використовувати setData()
метод, можна використовувати getData()
метод з dataTransfer
об'єкта. Це поверне id
пункт, який ми скидаємо. Ми хочемо додати наш елемент до цілі. Використовуючи стандартний JavaScript, ми можемо це зробити;
x-on:drop.prevent="
const id = event.dataTransfer.getData('text/plain');
const target = event.target.closest('ul');
const element = document.getElementById(id);
target.appendChild(element);
"
Код
Тепер у нас є всі окремі частини для побудови компонента перетягування. Складаючи все це воєдино, це повинно виглядати так;
<div class="drag-and-drop" x-data="{ adding: false, removing: false }">
<div class="drag-and-drop__container drag-and-drop__container--from">
<h3 class="drag-and-drop__title">From</h3>
<ul
class="drag-and-drop__items"
:class="{ 'drag-and-drop__items--removing': removing }"
x-on:drop="removing = false"
x-on:drop.prevent="
const id = event.dataTransfer.getData('text/plain');
const target = event.target.closest('ul');
const element = document.getElementById(id);
target.appendChild(element);
"
x-on:dragover.prevent="removing = true"
x-on:dragleave.prevent="removing = false">
<li
id="item-1"
class="drag-and-drop__item"
:class="{ 'drag-and-drop__item--dragging': dragging }"
x-on:dragstart.self="
dragging = true;
event.dataTransfer.effectAllowed = 'move';
event.dataTransfer.setData('text/plain', event.target.id);
"
x-on:dragend="dragging = false"
x-data="{ dragging: false }"
draggable="true">
Your Item #1
</li>
</ul>
</div>
<div class="drag-and-drop__divider">⇄</div>
<div class="drag-and-drop__container drag-and-drop__container--to">
<h3 class="drag-and-drop__title">To</h3>
<ul
class="drag-and-drop__items"
:class="{ 'drag-and-drop__items--adding': adding }"
x-on:drop="adding = false"
x-on:drop.prevent="
const id = event.dataTransfer.getData('text/plain');
const target = event.target.closest('ul');
const element = document.getElementById(id);
target.appendChild(element);
"
x-on:dragover.prevent="adding = true"
x-on:dragleave.prevent="adding = false">
</ul>
</div>
</div>
Резюме
Сподіваюся, ви знайшли цей підручник корисним, особливо якщо ви новачок у світі Alpine.js.
Це дуже проста реалізація перетягування з мінімальним JavaScript завдяки Alpine.js. Він все ще потребує вдосконалення, наприклад, для підтримки повторного замовлення в кожному списку. Але це відчувається як хороша відправна точка.
Особисто я б зараз почав переміщати JavaScript в окремий файл. Я б зберіг прив'язку до події і перемикання класів в HTML, але довші блоки JavaScript були б більш підтримуваними в конкретному файлі JavaScript.
Попередній перегляд
Ви можете переглянути цей код у дії на демонстрації Codepen.