Реализуйте draggable-polyfill, который украсит родное перетаскивание

JavaScript

Перетащите реализацию

До того, как 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;
})

родное перетаскивание

У нативного перетаскивания много преимуществ, вы можете узнать об этом сами, так же, как и о разнице между нативом и симулятором.

Тем не менее, те, кто немного эстетичен, определенно не будут использовать встроенное перетаскивание по умолчанию, потому что это действительно не очень красиво.

Давайте посмотрим на собственный эффект перетаскивания.

родной эффект перетаскивания

Собственный эффект перетаскивания по умолчанию представляет собой полупрозрачное изображение предварительного просмотра (на данный момент называемое «призрак»). Если размер перетаскиваемого элемента относительно мал, сгенерированное изображение предварительного просмотра приемлемо, но оно только полупрозрачное, как показано ниже.

image

Если больше, то недопустимо.«Призрак» не только полупрозрачный, но и имеет эффект градиента, который распространяется от положения мыши (правда не знаю, как он устроен, может быть, это из соображений производительности) , это все равно некрасиво.Ну как следует

image

Во-вторых, есть еще один эффект, что перетаскиваемый элемент остается на месте, а перетаскиваемый "призрак" движется. Если фон немного сложнее, то он будет совершенно неразличим, например порядок перетаскивания ниже (внимательно ищите "призрак" " над)

dragsort

Функция есть, но толком непонятная, да и опыта нет.

Пользовательское встроенное перетаскивание

Собственное перетаскивание в принципе невозможно настроить, единственное, что можно изменить, этоsetDragImageметод, вы можете указать изображение предварительного просмотра вместо изображения предварительного просмотра по умолчанию, но этот метод также очень безвкусен, пользовательское изображение предварительного просмотра все еще такое же, как эффект по умолчанию, оно полупрозрачно, а во-вторых, предварительный просмотр текущего узла генерируемые в режиме реального времени графики также вызывают затруднения.

Другой способ мышления на самом деле проще, а именно:

  1. удалить предварительный просмотр по умолчанию
  2. Скопируйте копию текущего целевого элемента, cloneObj
  3. Слушайте события перетаскивания и меняйте положение cloneObj
  4. Перетащите, чтобы удалить 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Дальше эффект такой

dragsort2

адрес проекта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, чтобы увидеть эффект перетаскивания (ниже).

drag