Использование технологии 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 объекта
Для того, чтобы объект можно было полноценно перетаскивать, необходимо отслеживать 3 разных события: dragEnter, dragOver и drop:
<div id="big" ondragenter="return dragEnter(event)" ondrop="return dragDrop(event)" ondragover="return dragOver(event)"></div>
Теперь необходимо написать соответствующие функции, начнем с событий dragenter и dragover:
function dragEnter(ev) { ev.preventDefault(); return true; } function dragOver(ev) { ev.preventDefault(); }
В первой функции мы определяем поведение объекта, который мы перетаскиваем, когда он достигает целевого элемента. В нашем примере мы предотвращаем стандартное действие браузера, но вы можете совершать любые действия: сменить фон или добавить текста, что бы пользователь понимал, что тащит объект туда, куда нужно, а с помощью события 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)">
Этого будет достаточно, чтобы квадраты можно было вернуть на место.
На этом всё!
Нет комментариев