Как настроить перетаскивание элементов с помощью HTML и JavaScript
Мышь: Drag’n’Drop более глубоко
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
В предыдущей статье мы рассмотрели основы Drag’n’Drop. Здесь мы разберём дополнительные «тонкие места» и приёмы реализации, которые возникают на практике.
Почти все javascript-библиотеки реализуют Drag’n’Drop так, как написано (хотя бывает что и менее эффективно).
Зная, что и как, вы сможете легко написать свой код переноса или поправить, адаптировать существующую библиотеку под себя.
Этот материал не строго обязателен для изучения, он специфичен именно для Drag’n’Drop.
Документ
Как пример задачи – возьмём документ с иконками браузера («объекты переноса»), которые можно переносить в компьютер («цель переноса»):
- Элементы, которые можно переносить (иконки браузеров), помечены классом draggable .
- Элементы, на которые можно положить (компьютер), имеют класс droppable .
Работающий пример с переносом:
Далее мы рассмотрим, как делается фреймворк для таких переносов, а в перспективе – и для более сложных.
- Поддержка большого количества элементов без «тормозов».
- Продвинутые возможности по анимации переноса.
- Удобная обработка успешного и неудачного переноса.
Начало переноса
Чтобы начать перенос элемента, мы должны отловить нажатие левой кнопки мыши на нём. Для этого используем событие mousedown … И, конечно, делегирование.
Переносимых элементов может быть много. В нашем документе-примере это всего лишь несколько иконок, но если мы хотим переносить элементы списка или дерева, то их может быть 100 штук и более.
Поэтому повесим обработчик mousedown на контейнер, который содержит переносимые элементы, и будем определять нужный элемент поиском ближайшего draggable вверх по иерархии от event.target .
В качестве контейнера здесь будем брать document , хотя это может быть и любой элемент.
Найденный draggable -элемент сохраним в свойстве dragObject.elem и начнём двигать.
Код обработчика mousedown :
Ранее мы по mousedown начинали перенос.
Но на самом деле нажатие на элемент вовсе не означает, что его собираются куда-то двигать. Возможно, на нём просто кликают.
Это важное различие. Снимать элемент со своего места и куда-то двигать нужно только при переносе.
Чтобы отличить перенос от клика, в том числе – от клика, который сопровождается нечаянным перемещением на пару пикселей (рука дрогнула), мы будем запоминать в dragObject , какой элемент ( elem ) и где ( downX/downY ) был зажат, а начало переноса будем инициировать из mousemove , если он передвинут хотя бы на несколько пикселей.
Перенос элемента
Первой задачей обработчика mousemove является инициировать начало переноса, если элемент передвинули в зажатом состоянии.
Ну а второй задачей – отображать его перенос при каждом передвижении мыши.
Схематично, обработчик будет иметь такой вид:
Здесь мы видим новое свойство dragObject.avatar . При начале переноса «аватар» делается из элемента и сохраняется в свойство dragObject.avatar .
«Аватар» – это DOM-элемент, который перемещается по экрану.
Почему бы не перемещать по экрану сам draggable -элемент? Зачем, вообще, нужен аватар?
Дело в том, что иногда сам элемент передвигать неудобно, например потому, что он слишком большой. А удобно создать некоторое визуальное представление элемента, и его уже переносить. Аватар даёт такую возможность.
А в простейшем случае аватаром можно будет сделать сам элемент, и это не повлечёт дополнительных расходов.
Визуальное перемещение аватара
Для того, чтобы отобразить перенос аватара, достаточно поставить ему position: absolute и менять координаты left/top .
Для использования абсолютных координат относительно документа, аватар должен быть прямым потомком BODY .
Следующий код готовит аватар к переносу:
… А затем его можно двигать:
Как вычислять новые координаты left/top при переносе?
Чтобы элемент сохранял свою позицию под курсором, необходимо при нажатии запомнить его изначальный сдвиг относительно курсора, и сохранять его при переносе.
Этот сдвиг по горизонтали обозначен shiftX на рисунке выше. Аналогично, есть shiftY . Они вычисляются как расстояние между курсором и левой/верхней границей элемента при mousedown . Детали вычислений описаны в главе Мышь: Drag’n’Drop.
Таким образом, при mousemove мы будем назначать элементу координаты курсора с учётом сдвига shiftX/shiftY :
Полный код mousemove
Код mousemove , решающий задачу начала переноса и позиционирования аватара:
Здесь используются две функции для начала переноса: createAvatar(e) и startDrag(e) .
Функция createAvatar(e) создаёт аватар. В нашем случае в качестве аватара берётся сам draggable элемент. После создания аватара в него записывается функция avatar.rollback , которая задаёт поведение при отмене переноса.
Как правило, отмена переноса влечёт за собой разрушение аватара, если это был клон, или возвращение его на прежнее место, если это сам элемент.
В нашем случае для отмены переноса нужно запомнить старую позицию элемента и его родителя.
Функция startDrag(e) , которую вызывает mousemove , если видит, что элемент в «зажатом» состоянии перенесли достаточно далеко, инициирует начало переноса и позиционирует аватар на странице:
Окончание переноса
Окончание переноса происходит по событию mouseup .
Его обработчик можно поставить на аватаре, т.к. аватар всегда под курсором и mouseup происходит на нем. Но для универсальности и большей гибкости (вдруг мы захотим перемещать аватар рядом с курсором?) поставим его, как и остальные, на document .
Задача обработчика mouseup :
- Обработать успешный перенос, если он идёт (существует аватар)
- Очистить данные dragObject .
Это даёт нам следующий код:
Для завершения переноса в функции finishDrag(e) нам нужно понять, на каком элементе мы находимся, и если над droppable – обработать перенос, а нет – откатиться:
Определяем элемент под курсором
Чтобы понять, над каким элементом мы остановились – используем метод document.elementFromPoint(clientX, clientY), который мы обсуждали в разделе координаты. Этот метод получает координаты относительно окна и возвращает самый глубокий элемент, который там находится.
Функция findDroppable(event) , описанная ниже, использует его и находит самый глубокий элемент с атрибутом droppable под курсором мыши:
Обратите внимание – для elementFromPoint нужны координаты относительно окна clientX/clientY , а не pageX/pageY .
Вариант выше – предварительный. Он не будет работать. Если попробовать применить эту функцию, будет все время возвращать один и тот же элемент! А именно – текущий переносимый. Почему так?
…Дело в том, что в процессе переноса под мышкой находится именно аватар. При начале переноса ему даже z-index ставится большой, чтобы он был поверх всех остальных.
Аватар перекрывает остальные элементы. Поэтому функция document.elementFromPoint() увидит на текущих координатах именно его.
Чтобы это изменить, нужно либо поправить код переноса, чтобы аватар двигался рядом с курсором мыши, либо дать аватару стиль pointer-events:none (кроме IE10-), либо:
- Спрятать аватар.
- Вызывать elementFromPoint .
- Показать аватар.
Напишем функцию findDroppable(event) , которая это делает:
DragManager
Из фрагментов кода, разобранных выше, можно собрать мини-фреймворк.
Объект DragManager будет запоминать текущий переносимый объект и отслеживать его перенос.
Для его создания используем не обычный синтаксис <. >, а вызов new function . Это позволит прямо при создании объявить дополнительные переменные и функции в замыкании, которыми могут пользоваться методы объекта, а также назначить обработчики:
Всю работу будут выполнять обработчики onMouse* , которые оформлены как локальные функции. В данном случае они ставятся на document через on. , но это легко поменять на addEventListener .
Код функции onMouse* мы подробно рассмотрели ранее, но вы сможете увидеть их в полном примере ниже.
Внутренний объект dragObject будет содержать информацию об объекте переноса.
У него будут следующие свойства, которые также разобраны выше:
elem Текущий зажатый мышью объект, если есть (ставится в mousedown ). avatar Элемент-аватар, который передвигается по странице. downX/downY Координаты, на которых был клик mousedown shiftX/shiftY Относительный сдвиг курсора от угла элемента, вспомогательное свойство вычисляется в начале переноса.
Задачей DragManager является общее управление переносом. Что же касается действий при его окончании – их должен назначить внешний код, который использует DragManager .
Можно сделать это через вспомогательные методы onDrag* , которые устанавливаются внешним кодом и затем вызываются фреймворком. Разработчик, подключив DragManager , описывает в этих методах, что делать при завершении или отмене переноса. Конечно же, можно заменить методы onDrag* на генерацию «своих» событий.
С использованием DragManager пример, с которого начиналась эта глава – перенос иконок браузеров в компьютер, реализуется совсем просто:
Полный пример с кодом:
Расширения
Существует масса возможных применений Drag’n’Drop. Здесь мы не будем реализовывать их все, поскольку не стоит цель создать фреймворк-монстр.
Однако, мы рассмотрим их, чтобы, при необходимости, легко было написать то, что нужно.
Захватывать элемент можно только за «ручку»
Часто бывает, что перенос должен быть инициирован только при захвате за определённую зону элемента. К примеру, модальное окно можно «взять», только захватив его за заголовок.
Для этого достаточно добавить необходимую проверку, к примеру, в функцию createAvatar или перед её запуском.
Если mousedown был внутри элемента, помеченного, к примеру, классом draghandle , то начинаем перенос, иначе – нет.
Проверка прав на droppable
Бывает и так, что не на любое место в droppable можно положить элемент.
Например: в админке есть дерево всех объектов сайта: статей, разделов, посетителей и т.п.
- В этом дереве есть узлы различных типов: «статьи», «разделы» и «пользователи».
- Все узлы являются переносимыми объектами.
- Узел «статья» (draggable) можно переносить в «раздел» (droppable), а узел «пользователи» – нельзя. Но и то и другое можно поместить в «корзину».
Здесь решение: можно переносить или нельзя зависит от «типа» переносимого объекта.
Есть и более сложные варианты, когда решение зависит от конкретного места в droppable , над которым посетитель отпустил кнопку мыши. К примеру, переносить в верхнюю часть можно, а в нижнюю – нет.
Эта задача решается добавлением проверки в findDroppable(e) . Эта функция знает и об аватаре и о событии, включая координаты. При попытке положить в «неправильное» место функция findDroppable(e) должна возвращать null .
Однако, на практике бывают ситуации, когда решение «прямо сейчас» принять невозможно. Например, нужно сделать запрос на сервер: «А разрешено ли текущему посетителю производить такую операцию?»
Как при этом должен вести себя интерфейс? Можно, конечно сделать, чтобы элемент после отпускания кнопки мыши «завис» над droppable , ожидая ответа. Однако, такое решение неудобно в реализации и странновато выглядит для посетителя.
Как правило, применяют «оптимистичный» алгоритм, по которому мы считаем, что перенос обычно успешен, но при необходимости можем отменить его.
При нём посетитель кладёт объект туда, куда он хочет, а затем, в коде onDragEnd :
- Визуально обрабатывается завершение переноса, как будто все ок.
- Производится асинхронный запрос к серверу, содержащий информацию о переносе.
- Сервер обрабатывает перенос и возвращает ответ, все ли в порядке.
- Если нет – выводится ошибка и возвращается avatar.rollback() . Аватар в этом случае должен предусматривать возможность отката после успешного завершения.
Процесс общения с сервером сопровождается индикацией загрузки и, при необходимости, блокировкой новых операций переноса до получения подтверждения.
Подсветка текущего droppable
Удобно, когда пользователь во время переноса наглядно видит, куда он сейчас положит draggable. Например, текущий droppable (или его часть) подсвечиваются.
Для этого в DragManager можно добавить дополнительные методы интеграции с внешним кодом:
- onDragEnter – будет вызываться при заходе на droppable , из onMouseMove .
- onDragMove – при каждом передвижении внутри droppable , из onMouseMove .
- onDragLeave – при выходе с droppable , из onMouseMove и onMouseUp .
Возможен более сложный вариант, когда нужно поддерживать не только перенос в элемент, но и перенос между элементами, например вставку одной статьи между двумя другими.
Для этого код, который обрабатывает перенос, может «делить на части» droppable, к примеру, в соотношении 25% – 50% – 25%, и смотреть:
- Если перенос в верхнюю четверть, то это – «над».
- Если перенос в середину, то это «внутрь».
- Если перенос в нижнюю четверть, то это – «под».
Текущий droppable и позиция относительно него при этом могут помечаться подсветкой и жирной чертой над/под, если требуется.
Пример индикации из Firefox:
Анимация отмены переноса
Отмену переноса и возврат аватара на место можно красиво анимировать.
Один из частых вариантов – скольжение объекта обратно к исходному месту, откуда его взяли. Для этого достаточно поправить avatar.rollback() .
Итого
Уточнённый алгоритм Drag’n’Drop:
- При mousedown запомнить координаты нажатия.
- При mousemove инициировать перенос, как только зажатый элемент передвинули на 3 пикселя или больше. Сообщить во внешний код вызовом onDragStart . При этом:
- Создать аватар, если можно начать перенос элемента draggable с данной позиции курсора.
- Переместить аватар по экрану, установив его новую позицию из e.pageX/pageY с учётом изначального сдвига элемента относительно курсора.
- Сообщить во внешний код о текущем droppable под курсором и позиции над ним вызовами onDragEnter , onDragMove , onDragLeave .
- При mouseup обработать завершение переноса. Элемент под аватаром получить по координатам, предварительно спрятав аватар. Сообщить во внешний код вызовом onDragEnd .
Получившаяся реализация Drag’n’Drop проста, эффективна, изящна.
Её очень легко поменять или адаптировать под «особые» потребности.
ООП-вариант фреймворка находится в статье Применяем ООП: Drag’n’Drop++.
Как настроить перетаскивание элементов с помощью HTML и JavaScript
В интернете можно найти множество руководств о том, как сделать элементы веб-сайта перетаскиваемыми. jQuery – это один простейших подходов.
Вам даже не потребуется jQuery UI, а просто немного помощи от функции направления курсора мыши. Но что если вам не хочется трогать код jQuery, но при этом хотите сделать элементы перетаскиваемыми? Тогда вам точно подойдет Draggabilly.js.
С помощью Draggabilly.js вы можете сделать любой веб-элемент перетаскиваемым. Вы можете настраивать поведение перетаскиваемых элементов и, к примеру, добавить сетку, по которой его можно перемещать, привязывать слушателей событий к событиям, ограничивать перемещение по осям x и y, а также многое другое. Стоит отметить, что эта библиотека поддерживает множество браузеров, включая IE8+ и мобильные браузеры с поддержкой мультитач.
Приступаем к работе
Для начала вам потребуется включить Draggabilly.js на сайт. И больше не потребуется других зависимых элементов. Вы можете скачать файл с GitHub.
Что касается всего остального, то вам нужно будет поработать с javascript-функцией.
Вам нужно внедрить следующий фрагмент кода в страницу, чтобы элементы стали перетаскиваемыми.
#idHere – это id, который нужно поместить внутрь HTML-элемента, который вам нужно сделать перетаскиваемыми. В то же время в переменную draggie вы можете поместить опцию. Если вам не нужна эта функция, вы также можете определить id посредством переменой elem.
К примеру, если у нас имеется id #demo без каких-либо опций, то мы можем создать сниппет следующего образца:
Затем внутри HTML вызовите id элемента, который вам нужно сделать перетаскиваемым. Далее следует базовый пример:
Существует множество иных способов повлиять на работу draggabilly. Вы можете ограничить перетаскивание только по определенным значениям на осях X и Y.
Либо вы можете добавить опцию управления, посредством которой можно будет указывать первичный элемент в рамках перемещения:
Данная опция .handle очень удобна при работе с внутренними элементами типа элементов ввода и форм, которые не должны быть перетаскиваемыми. К тому же, за вами остается возможность использовать и другие опции в виде сеток, методов и событий. Перейдите на официальный сайт draggabilly, чтобы ознакомиться с полной документацией.
Функция перетаскивания, во многих случаях, оказывает не очень сильное воздействие на веб-дизайн, однако остается очень важной. Ее часто можно встретить в веб-играх или приложениях. Простота установки данной библиотеки делает ее незаменимой в случаях, когда вам необходимо реализовать подобный функционал в собственных проектах!
jQuery UI Sortable — перетаскивание элементов
Перетаскивание элементов мышью это удобный прием для задания сортировки списков, таблиц, блоков и т.д. Самый простой способ это реализовать – использование плагина jQuery UI Sortable.
Параметры и события плагина можно посмотреть на http://api.jqueryui.com/sortable/.
Перетаскивание списков
Нужно только подключить файлы скриптов jQuery, jQuery UI и вызвать плагин с селектором списка
-
.
Перетаскивание за определенный элемент
Если в списке нужно будет выделять и копировать текст, например в текстовых полях, то перемещение за всю область сделает это проблематичным. Поэтому делают перемещение кликнув по иконке, так можно сделать добавив параметр handle и указав в нем название ее класса.
Заблокировать элемент
Чтобы заблокировать элемент, нужно добавить к нему класс disabled и указать его в параметре cancel . Также добавить CSS стили для этого класса.
Добавить анимацию
В параметре revert указывается скорость анимации в миллисекундах, она появляется после отпускания элемента.
Многоуровневые списки
Если нужно сделать сортируемый многоуровневый список, то достаточно в вызове плагина указать кроме основного и вложенные
-
.
Перетаскивание строк таблицы
UI Sortable в основном ориентирован на списки, у таблиц нужен небольшой фикс т.к. при перетаскивании строки, ее ширина становится меньше чем сама таблица.
Перетаскивание элементов DOM
HTML DOM как с использованием Javascript создать узлы DOM
Доброго времени суток. хочу через Javascript по событию onclick добавить в html документ что то.
Свойства DOM элементов
Какая разница между свойствами DOM-элементов и атрибутами DOM-элементов? Например в ХТМЛ для.
Создание элементов DOM js
Здравствуйте! Есть вот такой php и скрипт в нем: 17
29.06.2012, 13:58 | |
29.06.2012, 23:01 | 5 |
30.06.2012, 06:48 | 6 |
30.06.2012, 14:20 [ТС] | 7 |
Вложения
|
|
30.06.2012, 14:26 | 8 |
05.07.2012, 10:47 [ТС] | 9 |
Так вы мне поможете. Добавлено через 20 часов 20 минут |
|
05.07.2012, 20:04 | 10 |
05.07.2012, 20:15 | 11 |
05.07.2012, 20:32 | 12 |
05.07.2012, 22:31 | 13 |
newJS, тут случай совсем иной — товарищ просто не умеет без ошибок переписывать. Он взял действующий код, чуть-чуть переделал имена переменных. Вот он и просит всех найти его ошибку — сам он это сделать не в состоянии. |
|
06.07.2012, 20:47 | 14 |
Архив взял, посмотрю. Добавлено через 1 час 0 минут Если цепляться к терминам, то окошко не модальное. (это чтобы народ не путал грешное с праведным) Добавлено через 12 часов 53 минуты HTML5 RocksПереводыВведениеУже много лет мы используем для упрощения сложных элементов интерфейса, таких как анимации, скругленные углы и перетаскивание, библиотеки JQuery и Dojo. Несомненно, внешняя привлекательность важна для создания качественных веб-сайтов, но зачем нужна библиотека для общих задач, которые используют все разработчики? Перетаскивание (drag and drop, DnD) – одна из важнейших функций в HTML5. Эта спецификация определяет событийный механизм, API JavaScript и дополнительную метку, показывающую, что все элементы на странице могут перетаскиваться . Вряд ли кто-то будет возражать против встраивания в браузер дополнительных функций. Реализованная в браузере функция перетаскивания означает более быстрые и управляемые веб-приложения. Обнаружение функцийМногие приложения, в которых используется перетаскивание, не могут без него обходиться. Представьте себе, что вам пришлось бы продумывать шахматную партию, не имея возможности перемещать фигуры. Несмотря на полную поддержку браузера, определять, реализовано ли в нем перетаскивание (или иная функция HTML5, выполняющая те же задачи), нужно для того, чтобы обеспечить решение, способное качественно уменьшать мощность. Если функция перетаскивания недоступна, работу приложения можно реализовать, подключив библиотеку. Если вам необходимы возможности API, вместо определения параметра User-Agent браузера используйте обнаружение функций. Одна из лучших библиотек для обнаружения функций называется Modernizr. Для каждой проверяемой функции Modernizr задает логическое значение. В результате получается очень короткий код проверки на наличие функции перетаскивания: Создание перетаскиваемого содержанияСделать объект перетаскиваемым очень легко: для этого используется атрибут draggable=true . Перетаскивание можно включать практически для любых элементов, в т. ч. изображений, ссылок, файлов и даже узлов DOM. В качестве примера начнем с создания перегруппируемых столбцов. Базовая метка может выглядеть примерно так: Следует отметить, что в большинстве браузеров перетаскивание выделенных фрагментов текста, изображений и элементов привязок с атрибутом href поддерживается по умолчанию. Например, при перетаскивании логотипа на веб-сайте google.com возникает фантомное изображение: Большинство браузеров поддерживают перетаскивание изображений по умолчанию. Его можно перенести в адресную строку, элемент и даже на рабочий стол. Чтобы сделать перетаскиваемыми другие типы содержания, необходимо использовать API перетаскивания HTML5. С помощью CSS3 можно представить разметку в виде столбцов. С добавлением атрибута cursor: move пользователи получают визуальный индикатор подвижности элемента: Результат (элементы могут перетаскиваться, но ничего не делают): В приведенном выше примере большинство браузеров создают фантомное изображение перетаскиваемого содержания. Другие (в частности FF) в ходе операции перетаскивания требуют отправки данных. В следующем разделе мы сделаем пример со столбцами более интересным, добавив прослушиватели для обработки модели событий перетаскивания. Прослушивание событий перетаскиванияДля контроля над процессом перетаскивания можно использовать целый ряд событий: Для обработки алгоритма перетаскивания необходимо понимать, где находятся исходный элемент (откуда начинается перетаскивание), полезные данные (что мы пытаемся перетащить) и цель (область, в которой должен оказаться объект). Исходным элементом может быть изображение, список, ссылка, файловый объект, блок HTML-кода, что угодно. Цель – это зона (или несколько зон) перетаскивания, принимающая данные, которые пользователь пытается перетащить. Помните о том, что не все элементы могут быть целью (например, изображения). 1. Начало перетаскиванияОпределив в содержании атрибуты draggable=»true» , добавьте обработчики событий dragstart , которые будут запускать последовательность перетаскивания для каждого столбца. Как только пользователь начнет перетаскивать столбец, этот код уменьшит его непрозрачность до 40%: Поскольку целью события dragstart является наш исходный элемент, установка для атрибута this.style.opacity значения 40% позволит пользователю видеть перемещение выбранного элемента. Нам осталось только вернуть 100-процентную непрозрачность столбцов после перетаскивания. Для решения этой задачи используется событие dragend . Подробнее мы рассмотрим его попозже. 2. dragenter, dragover и dragleaveДля создания дополнительных визуальных подсказок во время перетаскивания можно использовать обработчики событий dragenter , dragover и dragleave . Например, если перетаскиваемый объект оказывается над столбцом, граница последнего становится пунктирной. Это покажет пользователям, что столбцы тоже могут быть целью перетаскивания. В этом коде стоит отметить несколько моментов.
3. Завершение перетаскиванияДля обработки самого перетаскивания добавьте прослушиватель для событий drop и dragend . В этом обработчике необходимо переопределить поведение браузера по умолчанию для переносов (обычно это что-то вроде переадресации). Запретить событию засорять модель DOM можно с помощью функции e.stopPropagation() . Наш пример со столбцами не обойдется без события drop , но прежде необходимо кое-что доработать, удалив класс over из каждого столбца с помощью события dragend : Если вы тщательно следили за происходящим, то заметили, что перетаскивание столбцов в нашем примере по-прежнему не работает так, как нужно. Введем объект DataTransfer . Объект DataTransferСвойство DataTransfer – это то самое место, где реализуется перетаскивание. Оно содержит часть данных, отправляемых при выполнении этого действия. Объект dataTransfer устанавливается в событии dragstart , а считывается и обрабатывается в событии drop . При вызове функции e.dataTransfer.setData(format, data) содержанию объекта назначается MIME-тип, а полезные данные передаются в качестве аргументов. В нашем примере в качестве полезных данных выступает фактический HTML-код исходного столбца: Удобно, что у объекта dataTransfer есть также функция getData(format) , позволяющая доставлять перетаскиваемые данные по MIME-типу. Вот как выглядит измененный процесс перетаскивания столбца: Для удобства при перемещении столбцов я добавил глобальную переменную dragSrcEl . В функции handleDragStart() в ней хранится элемент innerHTML исходного столбца. Впоследствии его считывает функция handleDrop() , меняя местами HTML-код исходного и целевого столбцов. Свойства перетаскиванияОбъект dataTransfer обладает свойствами, которые создают визуальную подсказку для пользователей в процессе перетаскивания. Их также можно использовать для управления реакцией каждой цели перетаскивания на определенный тип данных. dataTransfer.effectAllowed Ограничивает «тип перетаскивания», которое пользователь может выполнять с элементом. Это свойство используется в модели обработки перетаскивания для инициализации объекта dropEffect во время событий dragenter и dragover . Это свойства может принимать следующие значения: none , copy , copyLink , copyMove , link , linkMove , move , all и uninitialized . dataTransfer.dropEffect Управляет реакцией, которую пользователь получает во время событий dragenter и dragover . Когда перетаскиваемый объект наводится на целевой элемент, указатель браузера принимает вид, соответствующий типу предполагаемой операции (например, копирование, перенос и т. д.). Свойство может принимать следующие значения: none , copy , link , move . e.dataTransfer.setDragImage(img element, x, y) Вместо использования «фантомного изображения», которое браузер создает по умолчанию, можно задать значок перетаскивания. Результат (при перетаскивании этих столбцов должен отображаться логотип Google): Перетаскивание файловС помощью API перетаскивания можно перетаскивать файлы с рабочего стола в веб-приложение, открытое в окне браузера. Кроме того, Google Chrome позволяет перетаскивать файловые объекты из окна браузера на рабочий стол. Перетаскивание с рабочего стола в браузерПеретаскивание файла с рабочего стола выполняется с помощью событий перетаскивания, как и для других типов содержания. Основное отличие заключается в обработчике события drop . Вместо использования объекта dataTransfer.getData() для доступа к файлам данные помещаются в свойство dataTransfer.files : Полное руководство по перетаскиванию файлов с рабочего стола в браузер приведено в разделе Перетаскивание как способ выбора статьи Чтение локальных файлов в JavaScript. Перетаскивание из браузера на рабочий столПолное руководство по перетаскиванию файлов из браузера на рабочий стол приведено в статье Перетаскивание файлов как из Gmail на веб-сайте CSS Ninja. ПримерыВот конечный вариант с улучшенным внешним видом и счетчиком перемещений: В этом примере со столбцами интересно то, что каждый из них является одновременно исходным объектом и целью перетаскивания. Чаще всего исходный и целевой элементы различаются. Посмотрите пример: html5demos.com/drag. ЗаключениеМодель перетаскивания в HTML5 сложнее, чем в других решениях, таких как интерфейс JQuery. Однако если у вас есть возможность задействовать встроенный API браузера, ее нужно использовать. В конце концов, в этом и заключается суть HTML5: стандартизировать и сделать доступным весь набор собственных возможностей браузера. Надеемся, что со временем в популярные библиотеки, в которых используется функция перетаскивания, будет включена поддержка HTML5 по умолчанию и возможность по-разному настраивать JS-решение. Перемещаемые элементы, которые при перетаскивании раздвигают другие элементыЗа исключением парочки почти мистических вещей, наподобие тех, что позволяют вручную изменять размер текстового поля, перемещаемые элементы в вебе — это территория JavaScript . Например, нажать на элемент, удерживать кнопку мыши, перетащить элемент, удерживая его кнопкой мыши, а затем поместить его в нужном месте, отпустив кнопку мыши. Или их сенсорные аналоги. К счастью, это уже хорошо освоенная территория. Но теперь пришло время экспериментов, наподобие JQuery UI предлагаемого Draggable (и других подобных методов), чтобы делать это еще проще. В последнее время я заметил, что пытаясь совершить определенное действие (смотрите заголовок этой статьи), я не могу сделать это с помощью JQuery UI . Но я смог сделать это вот как. Я пытался воссоздать эффект, как в боковой панели Keynote , где можно перетаскивать элементы, чтобы менять местами слайды. Вот как выглядит этот эффект: Вы можете получить что-то очень близкое к этому с помощью некоторых элементов базовой конфигурации JQuery UI . Мы используем здесь метод Сортировка . Он предназначен специально для сортировки списков, так как нам нужно. То есть он использует что-то похожее и на Перетаскивание , и на Отпускание одновременно. JQueryИ базовый HTML наподобие этого: « Заполнитель » в конфигурации является элементом (это достигается с помощью введения имени класса), который вставляется между слайдами. Слайд, который мы перемещаем « бросается », если вы отпускаете кнопку мыши. Вы можете задать его стиль по своему усмотрению с помощью CSS . Я сделал его похожим на прямоугольник с голубой полосой слева, как в Keynote : Проблема заключается в том, чтобы « растолкать с дороги » другие слайды в том месте, где мы хотим поместить элемент. И на этом месте появился наш слайд. Сперва я пытался решить эту проблему с помощью анимации @keyframes , увеличивая высоту заполнителя от 0 до высоты слайда, а затем вывести в этом месте элемент с помощью режима заполнения. Это работает для установки заполнителя на новом месте, но JQuery UI просто вырывает заполнитель из DOM , когда он убирается со старого места, что не позволяет осуществлять перемещение плавно. Таким образом, необходима дополнительная обработка. К счастью, ЭйДжей Кэнди нашел удобный способ сделать как раз то, что мне нужно. Следите за моей мыслью, с этого момента все будет немного сложнее:
После этого запускаем метод сортировки для всех оригинальных слайдов. И затем, когда вы начинаете перетаскивать слайд:
Когда перетаскивание завершилось, нужно:
Потребовалось достаточно много времени, чтобы продумать, как это все сделать, и получить именно тот код, который нужен. В этом примере я использовал для номеров слайдов псевдо-элементы, так что этот блок тоже должен быть включен в код. Вот как выглядит все вместе: JQueryВот демо версия . Бонусная функция : слайдам назначен класс, с помощью которого, когда элементы перемещаются, они мигают, точно как в Keynote . Дэвид ДеСандро разрабатывал несколько проектов, связанных, с панелями с перемещаемыми элементами. О некоторых из них вы возможно слышали, например Masonry или Isotope . У него также есть один проект, который называется Packery . Он использует алгоритм для упаковки панелей. Используя его элементы и элементы другого проекта, Dragabilly , вы можете создать такой же эффект , когда перетаскиваемый элемент раздвигает другие элементы. Для одномерных панелей прекрасно подходит наша демо-версия. Дэвид усовершенствовал мою демо-версию так, что она может работать и для двойной панели. А также смог оптимизировать код, который теперь стал меньше. Просмотреть результат на Codepen . Данная публикация представляет собой перевод статьи « Draggable Elements That Push Others Out Of Way » , подготовленной дружной командой проекта Интернет-технологии.ру Очередной блог фрилансеракоротко и полезно о веб-разработкеПростой, перетаскиваемый элемент на jQueryБывают случаи, когда вам может понадобиться создать перетаскиваемый элемент внутри вашего веб-приложения. Это отличная функциональность, однако, возможно вы хотите, чтобы элемент оставался на новом месте, после перетаскивания. В сегодняшней статье вы узнаете, как можно легко перетаскивать и закреплять в новом месте нужный элемент даже после перезагрузки страницы, с помощью захвата и хранения его X и Y координат. СценарийИтак, у вас есть элемент на странице. Вы можете перетаскивать его туда-сюда. Но, когда страница перезагружается, элемент возвращается на исходную позицию. И хотя нам нужно, чтобы элемент был перетаскиваемый, при этом нужно, чтобы наш элемент достаточно было перетащить один раз. Давайте рассмотрим простое решение, реализующее данную функциональность. НачалоДля этого примера нам понадобится библиотека jQuery, jQuery UI и плагин JQuery-JSON. Кроме этого, мы также будем использовать PHP и базу данных MySQL для разбора и хранения наших данных. Если вы новичок в jQuery, не беспокойтесь. JQuery — это расширяемая, быстрая и легковесная JavaScript-библиотека, которую легко и весело использовать. Библиотека имеет хорошо структурированную документацию и огромное сообщество. HTML и CSSНачнем с HTML-разметки и стилей для нашего примера. Сначала CSS: CSS – очень простой. Мы назначаем html и body нулевые свойства, для чистки внешних и внутренних отступов, далее устанавливаем значения высоты, ширины и другие свойства для наших элементов. — moz-border-radius и -webkit-border-radius – это два свойства, позволяющие нам создать закругленные углы (работает пока только в Mozilla Firefox и Safari 3) для наших элементов. Теперь, давайте взглянем на HTML: Как видите, мы создали очень простую страницу, в которую подключили наш CSS, библиотеку JavaScript и плагины, кроме того, страница содержит элементы, к которым мы будем применять некоторые эффекты и события. Обратите внимание, что файл jquery-ui представляет собой специальную сборку, включающую в себя только ядро и функции перетаскивания элементов. JavaScriptТеперь самое интересное! Сначала давайте рассмотрим базовые функции, которые мы будем использовать для применения некоторых эффектов к нашим элементам. Разберем все до основания. Поместите этот код ниже HTML, сразу после закрывающего тега body. Хорошо, давайте сделаем что-нибудь с данными, которые приходят от нашего JQuery. Сначала нужно создать простую базу данных, для хранения наших координат, которые мы впоследствии будем использовать для определения позиции нашего элемента. Затем, нам понадобится файл config.php, в котором будут записаны параметры подключения к базе данных, а затем мы перейдем к updatecords.php. SQL Config.php updatecoords.php Здесь все довольно просто. Первое, что мы делаем – это проверяем, были ли переданы данные в файл. Если это произошло, мы включаем наш файл с настройками config.php и назначаем переменной $data значение json_decode(passed post variable); json_decode – это PHP-функция, представленная в PHP 5.2.0, которая позволяет декодировать строку JSON. Поскольку наша переменная $data содержит массив данных, нам нужно разобрать его на части, чтобы получить нужные значения. Для этого мы пройдемся по массиву $data->coords () (который был получен из переменной order в JavaScript) и обработаем каждый элемент. В результате, из каждой пары ключ – значение будет создан объект списка, который мы в дальнейшем укажем и создадим переменную для его вывода. При этом мы будем использовать функцию preg_replace , для исключения ненужных символов. Кроме того, мы подготовим наши значения для вставки в базу данных, путем экранирования кавычек, и апострофов, с помощью функции mysqli_real_escape_string . Если все прошло хорошо, нам нужно будет вернуть успешный результат JavaScript. В заключениеТеперь, когда у нас уже все готово, для того чтобы получить координаты элемента и передать их в PHP для записи, нам понадобится изменить нашу HTML-разметку для отображения позиции элемента. Для этого, мы удалим простую HTML-разметку и создадим ее с помощью PHP: Здесь мы исполняем простой запрос к базе данных для выбора всех строк из таблицы coords. Затем мы вызываем цикл while, который определяет каждую выбранную нами строчку как $row . Теперь, мы можем назначить переменные равными каждой, индивидуальной строке, полученной из базы данных, и выводим их в соответствующем месте. Рассказать друзьямПонравилась статья? Лучший способ сказать спасибо — поделиться ссылкой в социальных сетях: Свободное перетаскивание элементов DOM моделиУважаемые пользователи! Мы благодарим Вас за то, что Вам интересен нашен контент, поэтому с каждым днем хотим становиться все лучше и лучше! Большое спасибо за вашу помощь и внимательность к нам! Возможность перетаскивать элементы при помощи jQuery UI на сегодняшний день очень востребована, но для тех, кому нужна какая-то альтернатива, мы хотим предложить отдельную миниатюрную js-библиотеку под названием Draggabilly. Библиотека работает со всеми современными браузерами (IE8+), и здесь имеется встроенная поддержка touch-событий. С помощью draggabilly.js вы можете сделать любой веб-элемент перетаскиваемым. Вы можете настраивать поведение перетаскиваемых элементов и, к примеру, добавить сетку, по которой его можно перемещать, привязывать слушателей событий к событиям, ограничивать перемещение по осям x и y, а также многое другое. HTML CSS JS containment — ограничивает область перетаскивания. Возможные значения: parent (родительский элемент, в данном случае TRUE), document (текущий документ), window (окно), [x1, y1, x2, y2] — координаты левого верхнего и правого нижнего угла допустимой области. handle — определяет, за какой элемент внутри данного осуществляется перетаскивание. У плагина draggable есть четыре метода, которые позволяют менять работу плагина после его инициализации: disable — временно запрещает работу всей функциональности плагина Draggable. enable — разрешает работу всей функциональности плагина Draggable (если она была запрещена). option — позволяет установить значения параметров плагина после его инициализации. Перетаскивание с использованием JavaScript (а не HTML5)?Я делаю офлайн-гибридное приложение для Android с помощью HTML5. Во всяком случае, функция перетаскивания HTML5 еще не поддерживается на Android, поэтому я хотел использовать какой-либо другой метод. Каковы другие способы реализации перетаскивания с использованием JavaScript? вы можете использовать jquery-ui-touch-punch или Mobile Drag And Drop для достижения перетаскивания на мобильных устройствах. Их можно найти по следующим ссылкам соответственно. Основы работы Drag and Drop с использованием JavaScript без какой-либо дополнительной библиотеки или встроенных функций HTML5 — это привязка к различным событиям мыши/касания в браузере; Когда запускается mousedown/touchstart, вы клонируете элемент, который был нажат (или переместите существующий элемент), и настройте его с абсолютной позицией, чтобы вы могли перемещать его по странице. Когда начинается перетаскивание, вы должны установить ссылку на элемент, который перетаскивается, чтобы ваши события движения могли отслеживать, что происходит в данный момент. После того, как это событие было запущено, и у вас есть ссылка на элемент, вы присоедините события mousemove/touchmove к документу и начнете слушать фактические движения. Когда активируются события mousemove/touchmove, вы можете использовать положение событий для перемещения элемента по экрану. Для лучшей производительности вы добавляете события mousemove/touchmove ко всему документу, а не только к одному элементу, иначе вы столкнетесь с проблемами, когда мышь будет двигаться быстрее, чем вы можете обновить элемент. Наконец, при запуске mouseup/touchhend вы можете использовать конечную позицию для вычисления против точки droppoint. Вы также освободите события mousemove/touchmove и любую ссылку на элемент, который будет перетаскиваться. Изменение порядка элементов списка с помощью перетаскиванияЯ использовал следующие html и ts для элементов списка перетаскивания из одного div в другой div. И TypScript содержит следующее: Его из Html5 drag and drop, и я могу перетащить элементы списка из div с классом listArea в div с классом buildArea. После удаления элементов списка пользователь может изменить порядок элементов списка, которые были сброшены в div buildArea. Например, данный заказ я перечисляю 1,2,3,4, 5 может измениться до любого порядка, например, 2,4,5,3,1 или чего-либо, чего хочет пользователь. На данный момент я использовал только угловые и машинописные тексты, а сторонний плагин не был добавлен, и мне также нужно результат без какой-либо третьей стороны или jquery. Я также искал вокруг этого, но не смог получить правильное решение и, следовательно, любезно помог мне добиться изменения порядка в Отброшенный список. |