Drag n Drop система

есть система Drag n Drop, система работает только для 1 слота, у каждого слота задан свой стиль, и вот как сделать, чтоб работало для каждого слота, чтоб картинка могла помещаться еще и в определенные слоты, а так же маленький вопрос, как добавить второй предмет, помимо clothes.png

let select_item //Записываем в нее итем с которым работаем


let id_slot;
let currentDroppable = null;
let id_save_slot //Чтобы вернуть на прежнее место если отпустил не в div .cell

document.onmousedown = function(event) {

  select_item = event.target.closest('.item'); //Запоминаем итем который захватили

  let shiftX = event.clientX - select_item.getBoundingClientRect().left;
  let shiftY = event.clientY - select_item.getBoundingClientRect().top;

  select_item.style.position = 'absolute';
  select_item.style.zIndex = 1000;
  document.body.append(select_item);

  moveAt(event.pageX, event.pageY);

  function moveAt(pageX, pageY) {
    select_item.style.left = pageX - shiftX + 'px';
    select_item.style.top = pageY - shiftY + 'px';
  }
  function onMouseMove(event) {
    moveAt(event.pageX, event.pageY);

    select_item.hidden = true;
    let elemBelow = document.elementFromPoint(event.clientX, event.clientY);
    select_item.hidden = false;

    if (!elemBelow) return;

    let droppableBelow = elemBelow.closest('.Rectangle_80');

    if (currentDroppable != droppableBelow) {
      if (currentDroppable) { // null если мы были не над droppable до этого события
        // (например, над пустым пространством)
        leaveDroppable(currentDroppable);
        id_save_slot = currentDroppable
      }
      currentDroppable = droppableBelow;
      if (currentDroppable) { // null если мы не над droppable сейчас, во время этого события
        // (например, только что покинули droppable)
        enterDroppable(currentDroppable);
      }
    }
    if (currentDroppable)  id_slot = currentDroppable;
    else id_slot = null //Если не в слоте div .cell -> далее вернет обратно
    console.log(id_slot)

  }



  function setItemSlot(item) {
    select_item.innerHTML = `<div class="item" id = "faa">`
      
     if(!item) { //Если нажали не в поле = возвращаем на место
        id_save_slot.innerHTML = `<div class="item"><img src="img/clothes.png" class="img" />
        <div class="name">Одежда</div></div>`
        return;
     }
     
     item.innerHTML = `<div class="item"><img src="img/clothes.png" class="img" />
     <div class="name">Одежда</div></div>`
  }
  document.addEventListener('mousemove', onMouseMove);
  
  document.onmouseup = function(event) {
    document.removeEventListener('mousemove', onMouseMove);

    //
    setItemSlot(id_slot); //Обрабатываем слот (передаем id_slot тот что запомнился при наводке в currentDroppable)
    leaveDroppable(id_slot)

    //
    select_item.onmouseup = null;
  };
};

function enterDroppable(elem) { //водим по слотам
  elem.style.background = 'white';
}

function leaveDroppable(elem) { //отпустили в слоте
  elem.style.background = '';
}

document.ondragstart = function() { //для плавного перемещения при захвате
  return false;
};


Ответы (1 шт):

Автор решения: Егор Банин

В программировании, если вы решили задачу для одного случая, нет никаких проблем решить её для любого количества таких же случаев. Надо просто поместить все специфичные детали в переменные и менять их по необходимости.

Вот упрощённый пример перетаскивания одного элемента в один слот:

let item = document.querySelector('.item');
let slot = document.querySelector('.slot');
slot.addEventListener('dragover', e => e.preventDefault())
slot.addEventListener('drop', () => {
  slot.appendChild(item);
});
.slot {
  border: 1px solid black;
  width: 40px;
  height: 40px;
  padding: 5px
}

.item {
  border: 1px dotted black;
  width: 40px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  box-sizing: border-box;
}

.container {
  display: flex;
  margin: 0 0 1em;
}
<div class="container">
    <div class="slot"></div>
</div>
<div class="container">
    <div class="item" draggable="true">?</div>
</div>

Чтобы это работало для нескольких элеметов и слотов, надо менять значения переменной item и slot. Это можно делать по-разному, например так:

let item;
let items = document.querySelectorAll('.item');
for (let i = 0; i < items.length; ++i) {
  items[i].addEventListener('dragstart', e => item = e.target);
}
document.addEventListener('dragover', e => e.preventDefault())
document.addEventListener('drop', e => {
  if (e.target.className == 'slot') {
    e.target.appendChild(item);
  }
});
.slot {
  border: 1px solid black;
  width: 40px;
  height: 40px;
  padding: 5px
}

.item {
  border: 1px dotted black;
  width: 40px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  box-sizing: border-box;
}

.container {
  display: flex;
  margin: 0 0 1em;
}
<div class="container">
    <div class="slot"></div>
    <div class="slot"></div>
    <div class="slot"></div>
</div>
<div class="container">
    <div class="item" draggable="true">?</div>
    <div class="item" draggable="true">?</div>
    <div class="item" draggable="true">?</div>
</div>

В вашем коде функция setItemSlot содержит HTML-код айтема. Чтобы функция могла использоваться для других айтемов, вам надо заменить этот html на переменную, значение которой менять в зависимости от того, какой айтем выбран.

→ Ссылка