Использование Drag and drop в HTML5
Долгое время для создания Drag&Drop интерфейсов использовались реализации на JavaScript, но браузеры не имели встроенной поддержки Drag&Drop. С приходом HTML5 современные браузеры позволяют легко создавать drag and drop интерфейсы. В этой статье мы рассмотрим основные принципы создания Drag&Drop интерфейсов.
Поддержка
Прежде чем начать: Drag&Drop поддерживают все основные современные браузеры, но не все >мобильные браузеры имеют полную поддержку.
События Drag and drop
На каждом шаге выполнения операции перетаскивания активируются разные события, таким образом браузер знает какой именно JavaScript код выполнять, события следующие:
- dragStart: срабатывает, когда пользователь начинает перетаскивать объект.
- dragEnter: срабатывает, когда перетаскиваемый объект попадает в целевую зону.
- dragOver: срабатывает, когда курсор оказывается поверх элемента во время перетаскивания.
- dragLeave: срабатывает, когда курсор оказывается вне элемента во время перетаскивания.
- drag: срабатывает при движении мыши во время перетаскивания.
- drop: срабатывает, когда объект отпустили в целевой позиции (происходит drop).
- dragEnd: срабатывает, когда пользователь отпускает перетаскиваемый объект.
Все эти события помогают осуществлять полный контроль вашего Drag&Drop интерфейса.
Объект dataTransfer
Вся магия происходит здесь, этот объект содержит всю информацию о перетаскивании. Основные свойства и методы объекта:
- dataTransfer.effectAllowed=value: возвращает тип действия, допустимые значения: none, copy, copyLink, copyMove, link, linkMove, move, all и uninitialized.
- dataTransfer.setData(format, data): добавляет переданные данные и их формат.
- dataTransfer.clearData( format ): удаляет все данные заданного формата.
- dataTransfer.setDragImage(element, x, y): устанавливает изображение, которое вы хотите перетаскивать и положение курсора (0, 0 — верхний левый угол).
- data = dataTransfer.getData(format): возвращает данные, соответствующие формату.
Пример
Создадим небольшой пример Drag&Drop интерфейса.
Перетаскивание объекта
Начнем, как всегда, с HTML разметки. Создадим два перетаскиваемых элемента с помощью атрибута draggable:
<div id="boxA" draggable="true"></div>
После нам потребуется функция JavaScript, которая будет вызвана при перетаскивании объекта:
function dragStart(ev) { ev.dataTransfer.effectAllowed = 'move'; ev.dataTransfer.setData("Text", ev.target.getAttribute('id')); ev.dataTransfer.setDragImage(ev.target, 100, 100); return true; }
Этот код устанавливает тип допустимого эффекта — move, во второй строке мы устанавливаем данные для операции — тип — Text и значение — ID перетаскиваемого элемента. После используется метод setDragImage для установки того, что мы будем перетаскивать и, так как мы будем тащить квадраты размера 200 на 200px, курсор будет установлен в центр. И, наконец, функция возвращает true.
Drop объекта
<div id="big" ondragenter="return dragEnter(event)" ondrop="return dragDrop(event)" ondragover="return dragOver(event)"></div>
Для того, чтобы объект можно было полноценно перетаскивать, необходимо отслеживать 3 разных события: dragEnter, dragOver и drop:
function dragEnter(ev) { ev.preventDefault(); return true; } function dragOver(ev) { ev.preventDefault(); }
Теперь необходимо написать соответствующие функции, начнем с событий dragenter и dragover:
В первой функции мы определяем поведение объекта, который мы перетаскиваем, когда он достигает целевого элемента. В нашем примере мы предотвращаем стандартное действие браузера, но вы можете совершать любые действия: сменить фон или добавить текста, что бы пользователь понимал, что тащит объект туда, куда нужно, а с помощью события dragleave вы можете отменить сделанные изменения. В функции dragOver просто предотвращается стандартное действие браузера. Далее объявляем функцию, которая вызывается непосредственно, когда происходит drop объекта в нужном месте:
function dragDrop(ev) { var data = ev.dataTransfer.getData("Text"); ev.target.appendChild(document.getElementById(data)); ev.stopPropagation(); return false; }
В этой функции мы получаем все данные типа текст (это и будет объект, который мы тащим) и добавляем эти данные к целевому элементу. И, наконец, останавливаем всплытие (bubbling) события к родительским элементам и возвращаем false.
Как видно в демо, квадраты можно перетащить обратно в их начальную позицию. К счастью, добавить новую целевую позицию не так сложно: т. к. функции уже написаны, надо просто сослаться на них там, где необходимо:
Этого будет достаточно, чтобы квадраты можно было вернуть на место.
<section id="section" ondragenter="return dragEnter(event)" ondrop="return dragDrop(event)" ondragover="return dragOver(event)">
На этом всё!