@ArtemKornishon

Как сделать возможность посадить элемент при Drag'n'Drop на определенное место?

Здравствуйте!
При реализации учебного проекта по созданию мини-аналога трелло столкнулся с проблемой, что не могу разместить карту с задачей в колонке перед другими, или переместить в середину. Доступно только добавить ее вниз (appendChild)
Код полностью:
https://github.com/ArtemKornishon/ahj_dnd/blob/mai...
А так же песочница:
https://codepen.io/artemkornishon/pen/MWdVbyj

function dragOver(e) {
  e.preventDefault();
  if (e.target.classList.contains("column")) {
    let nextCard = actualCard.nextElementSibling
    console.log(nextCard)
    if (nextCard && nextCard.classList.contains("column__card")) {
        e.target.insertBefore(this, nextCard);
    } else {
      this.appendChild(actualCard);
    }
}
this.classList = 'column';
};


Пробовал реализовать вот так, по логике, что при наведении на столбец, условие должно проверять что за следующий элемент и вставить перед ним, но этот вариант либо не работает, либо работает очень криво.
Хотел бы получить помощи, потому что все идеи, что пришли в голову перепробовал, решения так и не нашел.
  • Вопрос задан
  • 196 просмотров
Решения вопроса 1
black1277
@black1277
Вольный стрелок
Примерно, вот так:

const deleteButton = document.querySelectorAll('.column__card-button');
const addButton = document.querySelector('.add_card')
const cardContent = document.querySelector('.column__card-content_add')
const columns = document.querySelectorAll('.column')
const columnTitle = document.querySelector('.column_title')
const mainContainer = document.querySelector('.main_container')
const toDoContainer = document.querySelector('.todo_container')
let actualCard = null;
const tasks = document.querySelectorAll('.column__card')
const areatxt = document.getElementById('textareaid')

addButton.addEventListener('click', function() {
  let columnCardText = areatxt.value;
  areatxt.value = ''
  const newColumnCard = `<div class="column__card" draggable="true"><div
  class="column__card-content">${columnCardText}</div><button class="column__card-button"></button></div>`
  columnTitle.insertAdjacentHTML("afterEnd", newColumnCard);
  //updateLocalStorage()
});

mainContainer.addEventListener('click', function(event) {
  if (event.target.classList.contains('column__card-button')) {
    const card = event.target.closest('.column__card');
    if (card) {
      card.remove();
    }
  }
  //updateLocalStorage()
});

function dragStart(e) {
  actualCard = e.target
  e.target.classList.add("is-dragging");
};

function dragEnd(e) {
  this.classList.remove('hovered');
};

function dragEnter(e) {
  e.preventDefault();
  this.classList.add('hovered');
};

function dragLeave() {
  this.classList.remove('hovered');
};

function dragOver(e) {
  e.preventDefault();
  const activeElement = mainContainer.querySelector(`.is-dragging`);
  const currentElement = e.target;
  
  const isMoveable = activeElement !== currentElement && currentElement.classList.contains(`column__card`);

  if (!isMoveable) {
    if (e.target.classList.contains("column") && !this.contains(actualCard)) {
      this.appendChild(actualCard);
    }    
    return;
  }
  // e.clientY — вертикальная координата курсора в момент,
  // когда сработало событие
  const nextElement = getNextElement(e.clientY, currentElement);

  // Проверяем, нужно ли менять элементы местами
  if (
    nextElement &&
    activeElement === nextElement.previousElementSibling ||
    activeElement === nextElement
  ) {
    return;
  }

  this.insertBefore(activeElement, nextElement);  
};
const getNextElement = (cursorPosition, currentElement) => {
  // Получаем объект с размерами и координатами
  const currentElementCoord = currentElement.getBoundingClientRect();
  // Находим вертикальную координату центра текущего элемента
  const currentElementCenter = currentElementCoord.y + currentElementCoord.height / 2;

  // Если курсор выше центра элемента, возвращаем текущий элемент
  // В ином случае — следующий DOM-элемент
  const nextElement = (cursorPosition < currentElementCenter) ?
      currentElement :
      currentElement.nextElementSibling;

  return nextElement;
};
for (const column of columns) {
  column.addEventListener('dragenter', dragEnter);
  column.addEventListener('dragleave', dragLeave);
  column.addEventListener('dragover', dragOver);
  column.addEventListener('drop', drop);
  column.addEventListener('dragstart', dragStart);
  column.addEventListener('dragend', dragEnd);
}

function drop(e) {
  e.preventDefault();
  actualCard.classList.remove("is-dragging");
  actualCard = null;
  this.classList.remove('hovered');
  //updateLocalStorage();
};


Запоминалку на LocalStorage рипнул только.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
22 нояб. 2024, в 11:53
3000 руб./за проект
22 нояб. 2024, в 11:51
20000 руб./за проект
22 нояб. 2024, в 11:50
200000 руб./за проект