Перетащите реализацию
До того, как HTML5 стал популярен, перетаскивание элементов было довольно проблематичным.Общая идея заключалась в том, чтобы отслеживать события, связанные с движением мыши.Ниже приведен псевдокод
oDiv.onmousedown = function(ev){
//记录起始位置
}
document.onmousemove = function(ev){
//移动目标元素
}
document.onmouseup = function(ev){
//取消鼠标移动事件
}
HTML5 добавляет перетаскиваниеdraggable
Стандартное перетаскивание становится простым, вам нужно только слушать события перетаскивания элементов, чтобы использовать различные функции перетаскивания.
<div draggable="true">drag me</div>
Кроме настройки
draggable="true"
свойства, по умолчаниюimg
, ссылки можно перетаскивать по умолчанию
Конечно, поставилdraggable="true"
Элемент можно только «перетаскивать», и он будет восстановлен после отпускания.Если вам нужно перетащить его в указанную позицию, вам нужно толькоdrop
Просто запишите это
dropbox.addEventListener('drop',function(ev){
dragbox.style.left = XX;
dragbox.style.top = XX;
})
родное перетаскивание
У нативного перетаскивания много преимуществ, вы можете узнать об этом сами, так же, как и о разнице между нативом и симулятором.
Тем не менее, те, кто немного эстетичен, определенно не будут использовать встроенное перетаскивание по умолчанию, потому что это действительно не очень красиво.
Давайте посмотрим на собственный эффект перетаскивания.
родной эффект перетаскивания
Собственный эффект перетаскивания по умолчанию представляет собой полупрозрачное изображение предварительного просмотра (на данный момент называемое «призрак»). Если размер перетаскиваемого элемента относительно мал, сгенерированное изображение предварительного просмотра приемлемо, но оно только полупрозрачное, как показано ниже.
Если больше, то недопустимо.«Призрак» не только полупрозрачный, но и имеет эффект градиента, который распространяется от положения мыши (правда не знаю, как он устроен, может быть, это из соображений производительности) , это все равно некрасиво.Ну как следует
Во-вторых, есть еще один эффект, что перетаскиваемый элемент остается на месте, а перетаскиваемый "призрак" движется. Если фон немного сложнее, то он будет совершенно неразличим, например порядок перетаскивания ниже (внимательно ищите "призрак" " над)
Функция есть, но толком непонятная, да и опыта нет.
Пользовательское встроенное перетаскивание
Собственное перетаскивание в принципе невозможно настроить, единственное, что можно изменить, этоsetDragImage
метод, вы можете указать изображение предварительного просмотра вместо изображения предварительного просмотра по умолчанию, но этот метод также очень безвкусен, пользовательское изображение предварительного просмотра все еще такое же, как эффект по умолчанию, оно полупрозрачно, а во-вторых, предварительный просмотр текущего узла генерируемые в режиме реального времени графики также вызывают затруднения.
Другой способ мышления на самом деле проще, а именно:
- удалить предварительный просмотр по умолчанию
- Скопируйте копию текущего целевого элемента, cloneObj
- Слушайте события перетаскивания и меняйте положение cloneObj
- Перетащите, чтобы удалить cloneObj
Далее идут псевдокоды, полный код можно посмотреть в конце статьи
1. Удалите изображение предварительного просмотра по умолчанию.
несмотря на то чтоsetDragImage
Это безвкусно, но мы можем установить прозрачное изображение, чтобы удалить изображение предварительного просмотра по умолчанию.
dragbox.addEventListener('dragstart', function (ev) {
var img = new Image();
img.src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' %3E%3Cpath /%3E%3C/svg%3E";
ev.dataTransfer.setDragImage(img, 0, 0);
}
Общие настройки элемента
draggable="true"
После этого Chrome может перетаскивать напрямую, FireFox должен быть вdragstart
настраиватьev.dataTransfer.setData('text','任意值')
просто делать
2. Скопируйте копию текущего целевого элемента cloneObj
Сделайте копию текущего целевого элемента и установитеposition:fixed
и другие атрибуты, которые можно приостановить на странице, а затем добавить вbody
,следующим образом
var cloneObj = this.cloneNode(true);
cloneObj.style = 'position:fixed;left:0;top:0;z-index:999;pointer-events:none;transform:translate3d( ' + left + 'px ,' + top + 'px,0);'
document.body.appendChild(cloneObj);
3. Прослушайте события перетаскивания и измените положение cloneObj.
Срабатывает при перетаскивании элементаdrag
Событие, аналогичное событию движения мыши, может получать текущую позицию мыши (событие mousemove не срабатывает в процессе перетаскивания), а также может скрывать исходную цель
dragbox.addEventListener('drag', function (ev) {
if(cloneObj){
cloneObj.style.transform = 'translate3d( ' + left + 'px ,' + top + 'px,0)';
dragbox.style.visibility = 'visible';
}
})
Chrome действительно имеет место, хотя FireFox также может запускатьdrag
событие, и тогда информация о позиции мыши (все 0) не может быть получена, поэтому мы можем только поместить прослушиватель наdragover
На хоть и не идеальный, но тоже метод
document.addEventListener('dragover', function (ev) {
if(cloneObj){
cloneObj.style.transform = 'translate3d( ' + left + 'px ,' + top + 'px,0)';
}
})
4. Перетащите, чтобы удалить cloneObj
После перетаскивания удалите cloneObj и восстановите исходную цель
oDiv.addEventListener('dragend', function (ev) {
document.body.removeChild(cloneObj);
cloneObj = null;
dragbox.style.visibility = 'visible';
})
draggable-polyfill
На основе изложенных выше идей А.draggable-polyfill
,этоpolyfill
Функция очень проста, она просто украшает собственное перетаскивание, удаляет исходное полупрозрачное изображение предварительного просмотра, не меняет исходную логику, если в проекте используется собственное перетаскивание, этот патч можно применить.
Например, приведенная выше сортировка методом перетаскивания, см.polyfill
Дальше эффект такой
адрес проектаGitHub.com/Xbox ypress/Конечно…
Он также очень прост в использовании, просто процитируйте его напрямую.
<script src="./lib/draggable-polyfill.js"></script>
Если это инженерный проект, вы также можете использоватьnpm
Установить
npm i draggable-polyfill
Затем импортируйте его напрямую
import draggable-polyfill;
Другие примеры можно посмотретьСиньбо сказал с улыбкой.Код Рабо.Талант/драг дан АБ - боюсь...
Следует отметить, что, поскольку копируется только текущий узел, если ваш стиль зависит от родителя, скопированный стиль будет отличаться от исходного целевого узла.
.parent .dragbox{
background:red
}
/*改为*/
.dragbox{
background:red
}
другие трюки
Вы можете найти родной кейс перетаскивания в Интернете и вставить вышеперечисленное прямо в консоль.draggable-polyfill.js
, вы можете сразу же «попробовать», например, этопример, откройте консоль для вставки и нажмите Enter, чтобы увидеть эффект перетаскивания (ниже).