Перемещение элементов js
Как реализовать перемещение блоков между собой так, чтобы элементы не "ломались" из-за того, что все элементы внутри блока так же переносятся.

const main = document.querySelector(".item_list");
main.querySelectorAll(".item").forEach((e) => {
e.ondragstart = (e) => {
e.dataTransfer.setData("id", e.target.id);
};
e.ondragover = (e) => {
e.preventDefault();
};
e.ondrop = (e) => {
let v = e.target.innerHTML;
let fromEl = document.querySelector("#" + e.dataTransfer.getData("id"));
e.target.innerHTML = fromEl.innerHTML;
fromEl.innerHTML = v;
};
});
.row {
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.menu {
height: 20px;
width: 700px;
border: 1px solid;
border-bottom: none;
background-color: #fff1eb;
}
.item_list {
width: 700px;
height: 500px;
display: flex;
flex-wrap: wrap;
background-color: #fffbeb;
border: 1px solid;
}
.item {
width: 150px;
height: 150px;
border: 1px solid;
text-align: center;
line-height: 50px;
font-size: 30px;
margin: auto;
background-color: #fff1eb;
}
.item__name {
font-size: 20px;
margin: 0;
}
.item__description {
font-size: 16px;
}
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<main class="row">
<div class="menu"></div>
<div class="item_list">
<div id="c1" class="item" draggable="true">
<span class="item__name">Коробка</span>
<span class="item__description">
Какая-то коробка
</span>
<button>
Купить
</button>
</div>
<div id="c2" class="item" draggable="true">
<span class="item__name">Коробка2</span>
<span class="item__description">
Какая-то коробка22
</span>
<button>
Купить22
</button>
</div>
<div id="c3" class="item" draggable="true">
<span class="item__name">Коробка3</span>
<span class="item__description">
Какая-то коробка23
</span>
<button>
Купить22
</button>
</div>
<div id="c4" class="item" draggable="true">
<span class="item__name">Коробка4</span>
<span class="item__description">
Какая-то коробка24
</span>
<button>
Купить22
</button>
</div>
<div id="c5" class="item" draggable="true">
<span class="item__name">Коробка5</span>
<span class="item__description">
Какая-то коробка5
</span>
<button>
Купить22
</button>
</div>
<div id="c6" class="item" draggable="true">
<span class="item__name">Коробка6</span>
<span class="item__description">
Какая-то коробка6
</span>
<button>
Купить22
</button>
</div>
<div id="c7" class="item" draggable="true">
<span class="item__name">Коробка7</span>
<span class="item__description">
Какая-то коробка7
</span>
<button>
Купить22
</button>
</div>
<div id="c8" class="item" draggable="true">
<span class="item__name">Коробка8</span>
<span class="item__description">
Какая-то коробка8
</span>
<button>
Купить22
</button>
</div>
<div id="c9" class="item" draggable="true">
<span class="item__name">Коробка9</span>
<span class="item__description">
Какая-то коробка9
</span>
<button>
Купить22
</button>
</div>
<div id="c10" class="item" draggable="true">
<span class="item__name">Коробка10</span>
<span class="item__description">
Какая-то коробка10
</span>
<button>
Купить22
</button>
</div>
<div id="c11" class="item" draggable="true">
<span class="item__name">Коробка11</span>
<span class="item__description">
Какая-то коробка11
</span>
<button>
Купить22
</button>
</div>
<div id="c12" class="item" draggable="true">
<span class="item__name">Коробка12</span>
<span class="item__description">
Какая-то коробка12
</span>
<button>
Купить22
</button>
</div>
</div>
</main>
<script src="src/index.js"></script>
</body>
</html>
Ответы (1 шт):
Автор решения: OPTIMUS PRIME
→ Ссылка
e.target — Элемент, на который реально тыкнули (кнопка, абзац и прочее, что находится внутри элемента). e.currentTarget — Элемент, на котором сработало событие (".item"). Будет работать как надо, если все target заменить на currentTarget.
А если использовать не стрелочные функции, e.currentTarget можно заменить на this (у стрелок нет this). Заодно вытащить их из цикла, чтобы на каждой итерации не создавалась новая функция, а использовалась одна и та же.
// ".item_list .item" — Селектор через пробел, «Все .item внутри .item_list»
document.querySelectorAll(".item_list .item").forEach((e) => {
e.addEventListener("dragstart", item_dragstart);
e.addEventListener("dragover", item_dragover);
e.addEventListener("drop", item_drop);
});
function item_dragstart(e) {
e.dataTransfer.setData("id", this.id);
}
function item_dragover(e) {
e.preventDefault();
}
function item_drop(e) {
let from = document.querySelector("#" + e.dataTransfer.getData("id"));
[this.innerHTML, from.innerHTML] = [from.innerHTML, this.innerHTML];
// Меняет местами значения («Деструктурирующее присваивание»)
}
.row {
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.menu {
height: 20px;
width: 700px;
border: 1px solid;
border-bottom: none;
background-color: #fff1eb;
}
.item_list {
width: 700px;
height: 500px;
display: flex;
flex-wrap: wrap;
background-color: #fffbeb;
border: 1px solid;
}
.item {
width: 150px;
height: 150px;
border: 1px solid;
text-align: center;
line-height: 50px;
font-size: 30px;
margin: auto;
background-color: #fff1eb;
}
.item__name {
font-size: 20px;
margin: 0;
}
.item__description {
font-size: 16px;
}
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<main class="row">
<div class="menu"></div>
<div class="item_list">
<div id="c1" class="item" draggable="true">
<span class="item__name">Коробка</span>
<span class="item__description">
Какая-то коробка
</span>
<button>
Купить
</button>
</div>
<div id="c2" class="item" draggable="true">
<span class="item__name">Коробка2</span>
<span class="item__description">
Какая-то коробка22
</span>
<button>
Купить22
</button>
</div>
<div id="c3" class="item" draggable="true">
<span class="item__name">Коробка3</span>
<span class="item__description">
Какая-то коробка23
</span>
<button>
Купить22
</button>
</div>
<div id="c4" class="item" draggable="true">
<span class="item__name">Коробка4</span>
<span class="item__description">
Какая-то коробка24
</span>
<button>
Купить22
</button>
</div>
<div id="c5" class="item" draggable="true">
<span class="item__name">Коробка5</span>
<span class="item__description">
Какая-то коробка5
</span>
<button>
Купить22
</button>
</div>
<div id="c6" class="item" draggable="true">
<span class="item__name">Коробка6</span>
<span class="item__description">
Какая-то коробка6
</span>
<button>
Купить22
</button>
</div>
<div id="c7" class="item" draggable="true">
<span class="item__name">Коробка7</span>
<span class="item__description">
Какая-то коробка7
</span>
<button>
Купить22
</button>
</div>
<div id="c8" class="item" draggable="true">
<span class="item__name">Коробка8</span>
<span class="item__description">
Какая-то коробка8
</span>
<button>
Купить22
</button>
</div>
<div id="c9" class="item" draggable="true">
<span class="item__name">Коробка9</span>
<span class="item__description">
Какая-то коробка9
</span>
<button>
Купить22
</button>
</div>
<div id="c10" class="item" draggable="true">
<span class="item__name">Коробка10</span>
<span class="item__description">
Какая-то коробка10
</span>
<button>
Купить22
</button>
</div>
<div id="c11" class="item" draggable="true">
<span class="item__name">Коробка11</span>
<span class="item__description">
Какая-то коробка11
</span>
<button>
Купить22
</button>
</div>
<div id="c12" class="item" draggable="true">
<span class="item__name">Коробка12</span>
<span class="item__description">
Какая-то коробка12
</span>
<button>
Купить22
</button>
</div>
</div>
</main>
<script src="src/index.js"></script>
</body>
</html>