Drag'n'Drop, позиционировать перенесённый элемент

349
14 июня 2017, 03:58

Как сделать, чтобы квадраты из нижнего ряда, когда их перетаскиваешь на пустые квадраты в верхний ряд не исчезали, а становились точно на их место. И псоле этого делались не перетаскиваемыми? Т.е. занимали место пустых и там и оставались.

Вот этот самый пример с квадратами на Plunker и кусок кода из него: http://plnkr.co/edit/vrPWYw5bf0BSeJM3Dph3?p=preview

    DragManager.onDragCancel = function(dragObject) {
      dragObject.avatar.rollback();
    };
    DragManager.onDragEnd = function(dragObject, dropElem) {
      dragObject.elem.style.display = 'none';
    };

Это изменённый код из вот этого урока learn.javascript. ru/drag-and-drop-objects

Как я понимаю, там нужно вписать в DragManager.onDragEnd (это в голове html) то поведение элемента, которое от него ожидаешь по окончании перетаскивания.

Мне нужно сделать, чтобы перетаскиваемый элемент заменял собой элемент, который его принимает. Или становился на те же координаты поверх него. И чтобы он после этого переставал быть перетаскиваемым, например терял бы класс draggable, который делает его перетаскиваемым.

Как это сделать? Что нужно дописать в DragManager.onDragEnd? Спасибо.

P.S. Чтобы не исчезали, просто убрать dragObject.elem.style.display = 'none', это ясно. Но тогда они вообще странно себя ведут. Им нужно явно задать как-то, куда им становиться по окончанию перетаскивания.

upd: Методом тыка выяснила, что на что нужно заменить:

    DragManager.onDragEnd = function(dragObject, dropElem, elem) {
      dropElem.parentNode.replaceChild(dragObject.elem, dropElem);
    };

Но замена происходит не так, как нужно. По окончании перетаскивания, старый узел удаляется, а новый становится не точно на его место, а там, где его бросили. Только если его двинуть второй раз, тогда он становится ровно на место прежнего. Как ему сделать, чтобы он с первого раза становился, куда нужно?

Ссылку на исправленный код добавила в комментарии.

upd2:

Разобралась, нужно было добавить dragObject.elem.style.position = 'inherit';

    DragManager.onDragEnd = function(dragObject, dropElem, elem) {          
      dragObject.elem.style.position = 'inherit';           
      dropElem.parentNode.replaceChild(dragObject.elem, dropElem);          
      dragObject.elem.classList.remove("draggable");              
    };

Итоговый вариант кода во втором комментарии. Всем спасибо.

Answer 1

Ответ:

Было две идеи насчёт решения. Либо по окончании перетаскивания расположить перетаскиваемый элемент поверх принимающего, по его координатам, либо же заменить принимающий элемент тем, который был перемещён.

В первом случае было не очень понятно, как взять координаты принимающего элемента. Наверное, это можно как-то сделать, но я не смогла. Сделала по второму варианту. Но там лично мне было сложно понять, что на что нужно заменять. Точнее, как эти два элемента, перемещаемый и принимающий прописаны в коде. Принимающий был прописан в самом DragManager.onDragEnd как dropElem, это было более-менее понятно сразу. А вот чтобы понять, что перемещаемый, это не dragObject, не elem, а dragObject.elem, на это и ушла вся ночь.

DragManager.onDragEnd = function(dragObject, dropElem, elem) {          
  dragObject.elem.style.position = 'inherit';           
  dropElem.parentNode.replaceChild(dragObject.elem, dropElem);          
  dragObject.elem.classList.remove("draggable");              
};

Вот и всё, что требовалось, собственно. В конце получилась заминка, после замещения принимающего элемента перемещаемым, последний не хотел сразу садиться на своё место. Как-то интуитивно поняла, что это из-за того, что у него position: absolute; Заменила на inherit, и всё заработало.

http://plnkr.co/edit/s7L76mxYTv7xNgLwrifJ?p=preview

Весь код я сюда не продублирую ну никак, там его слишком много и ещё стили и целый фреймворк в отдельном файле. Спасибо.

READ ALSO
Слайдер картинок через массив

Слайдер картинок через массив

Сделал слайдер через массив, но не могу придумать, как сделать 2 элемент массива background-position-y: -110px

432
Верстка stackoverflow, flex заменяется на inline-block

Верстка stackoverflow, flex заменяется на inline-block

Заметила, что верстка stackoverflow выполнена с помощью flex'ов

254