После перетаскивания блока из левого контейнера в правый контейнер он удаляется из левого контейнера. Как предотвратить удаление из левого контейнера и несколько раз перетаскивать одно и то же?
Я пробовал с этим кодом, и он не работает для меня.
Необходимо достичь - он не должен удаляться после перетаскивания в правильный контейнер, он всегда должен быть там, чтобы перетаскивать несколько раз
const blocksData = [{
id: 1,
label: 'Test Content',
htmlContent: '<h1>Test Content</h1>'
},
{
id: 2,
label: 'Test Content',
htmlContent: '<h2>Test Content</h2>'
},
{
id: 3,
label: 'Test Content',
htmlContent: '<h3>Test Content</h3>'
},
{
id: 4,
label: 'Test Content',
htmlContent: '<button>Test Content</button>'
},
];
const getDragAfterElement = (container, y) => {
console.info("Test 1");
const draggableElements = [...container.querySelectorAll('.block:not(.dragging)')]
return draggableElements.reduce((closest, child) => {
const box = child.getBoundingClientRect()
const offset = y - box.top - box.height / 2
if (offset < 0 && offset > closest.offset) {
return {
offset: offset,
element: child
}
} else {
return closest
}
}, {
offset: Number.NEGATIVE_INFINITY
}).element
}
const initiateHandler = () => {
console.info("Test 2");
const left = document.getElementsByClassName("left")[0];
const handle = document.getElementById("handle");
handle.draggable = true;
handle.addEventListener("mousedown", (e) => {
ismdwn = 1
document.body.addEventListener('mousemove', (e) => mV(e, left))
document.body.addEventListener('mouseup', (e) => end(e, handle))
});
}
const onReady = () => {
console.info("Test 3");
initiateHandler();
const drggableBlocksHolder = document.getElementById("blocks");
blocksData.map((block) => {
if (!document.querySelector("#blocks > div:nth-child(4)")) drggableBlocksHolder.innerHTML += `<div draggable = "true" class = "block" data-block = "${block.id}">${block.htmlContent}</div>`;
});
document.right = document.getElementsByClassName("right")[0];
document.draggables = blocks.getElementsByClassName("block");
document.draggable = document.querySelector('.dragging');
for (let index = 0; index < document.draggables.length; index++) {
const draggable = document.draggables[index];
draggable.addEventListener('dragstart', () => {
draggable.classList.add('dragging')
});
draggable.addEventListener('dragend', () => {
draggable.classList.remove('dragging')
});
}
document.right.addEventListener('dragover', (e) => {
console.info("Test 4");
e.preventDefault();
document.draggables = blocks.getElementsByClassName("block");
document.draggable = document.querySelector('.dragging');
const afterElement = getDragAfterElement(document.right, e.clientY)
if (afterElement == null) {
id = document.draggable.getAttribute('data-block')
document.draggable.innerHTML = blocksData[id - 1].htmlContent;
document.right.appendChild(document.draggable)
} else {
document.right.insertBefore(document.draggable, afterElement)
}
});
};
const mV = (event, left) => {
console.info("Test 5");
if (ismdwn === 1) {
left.style.flexBasis = event.clientX + "px"
} else {
end()
}
}
const end = (e) => {
console.info("Test 6");
ismdwn = 0
document.body.removeEventListener('mouseup', end)
handle.removeEventListener('mousemove', mV)
}
(function() {
console.info("Test 7");
onReady()
})();* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body,
html {
position: relative;
}
.container {
position: fixed;
width: 100%;
height: 100%;
display: flex;
}
.container>.left {
position: relative;
height: 100%;
border: 1px solid rgba(0, 0, 0, 0.2);
flex-grow: 1;
flex-shrink: 0;
flex-basis: 35%;
min-width: 300px;
}
.container>.left>.blocks {
display: flex;
flex-direction: column;
width: 100%;
}
.container>.left>h4 {
font-family: 'Roboto';
font-weight: bold;
margin: 10px auto;
font-size: 18px;
text-align: center;
}
.container>.left>.blocks>.block {
width: 100%;
padding: 10px 15px;
margin-top: 5px;
border: 1px solid rgba(0, 0, 0, 0.2);
cursor: move;
}
.block.dragging {
opacity: .5;
}
.container>.right {
width: 100%;
height: 100%;
border: 1px solid rgba(0, 0, 0, 0.2);
flex-grow: 0;
flex-shrink: 1;
overflow-x: auto;
}
.container>.handle {
background-color: rgba(0, 0, 0, 0.4);
content: '';
width: 7px;
cursor: col-resize;
flex-grow: 0;
flex-shrink: 0;
margin: 0 0 0 auto;
}<div class = "container">
<div class = "left">
<h4>Blocks</h4>
<div class = "blocks" id = "blocks">
<div draggable = "true" class = "block" data-block = "1">Test Block 1 H1</div>
<div draggable = "true" class = "block" data-block = "2">Test Block 1 H2</div>
<div draggable = "true" class = "block" data-block = "3">Test Block 1 H3</div>
<div draggable = "true" class = "block" data-block = "4">Test Block 1 button</div>
</div>
</div>
<div class = "handle" id = "handle"></div>
<div class = "right"></div>
</div>


![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я надеюсь, это то, что вы хотели. Блок удалялся из-за метода appendChild. Я заменил ребенка, пытающегося быть добавленным к клону перетаскиваемого блока. Пожалуйста, дайте мне знать, если вам нужно что-то еще.
const blocksData = [{
id: 1,
label: 'Test Content',
htmlContent: '<h1>Test Content</h1>'
},
{
id: 2,
label: 'Test Content',
htmlContent: '<h2>Test Content</h2>'
},
{
id: 3,
label: 'Test Content',
htmlContent: '<h3>Test Content</h3>'
},
{
id: 4,
label: 'Test Content',
htmlContent: '<button>Test Content</button>'
},
];
const getDragAfterElement = (container, y) => {
console.info("Test 1");
const draggableElements = [...container.querySelectorAll('.block:not(.dragging)')]
return draggableElements.reduce((closest, child) => {
const box = child.getBoundingClientRect()
const offset = y - box.top - box.height / 2
if (offset < 0 && offset > closest.offset) {
return {
offset: offset,
element: child
}
} else {
return closest
}
}, {
offset: Number.NEGATIVE_INFINITY
}).element
}
const initiateHandler = () => {
console.info("Test 2");
const left = document.getElementsByClassName("left")[0];
const handle = document.getElementById("handle");
handle.draggable = true;
handle.addEventListener("mousedown", (e) => {
ismdwn = 1
document.body.addEventListener('mousemove', (e) => mV(e, left))
document.body.addEventListener('mouseup', (e) => end(e, handle))
});
}
const onReady = () => {
console.info("Test 3");
initiateHandler();
const drggableBlocksHolder = document.getElementById("blocks");
blocksData.map((block) => {
if (!document.querySelector("#blocks > div:nth-child(4)")) drggableBlocksHolder.innerHTML += `<div draggable = "true" class = "block" data-block = "${block.id}">${block.htmlContent}</div>`;
});
document.right = document.getElementsByClassName("right")[0];
document.draggables = blocks.getElementsByClassName("block");
document.draggable = document.querySelector('.dragging');
for (let index = 0; index < document.draggables.length; index++) {
const draggable = document.draggables[index];
draggable.addEventListener('dragstart', () => {
draggable.classList.add('dragging')
});
draggable.addEventListener('dragend', () => {
draggable.classList.remove('dragging')
document.querySelector(".dragging").classList.remove("dragging")
});
}
document.right.addEventListener('dragover', (e) => {
console.info("Test 4");
e.preventDefault();
document.draggables = blocks.getElementsByClassName("block");
document.draggable = document.querySelector('.dragging');
const afterElement = getDragAfterElement(document.right, e.clientY)
document.draggableClone = document.draggable.cloneNode(true)
if (document.right.querySelector(".dragging") == undefined){
if (afterElement == null) {
id = document.draggable.getAttribute('data-block')
document.draggableClone.innerHTML = blocksData[id - 1].htmlContent;
document.right.appendChild(document.draggableClone)
} else {
document.right.insertBefore(document.draggableClone, afterElement)
}
}
});
};
const mV = (event, left) => {
console.info("Test 5");
if (ismdwn === 1) {
left.style.flexBasis = event.clientX + "px"
} else {
end()
}
}
const end = (e) => {
console.info("Test 6");
ismdwn = 0
document.body.removeEventListener('mouseup', end)
handle.removeEventListener('mousemove', mV)
}
(function() {
console.info("Test 7");
onReady()
})();* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body,
html {
position: relative;
}
.container {
position: fixed;
width: 100%;
height: 100%;
display: flex;
}
.container>.left {
position: relative;
height: 100%;
border: 1px solid rgba(0, 0, 0, 0.2);
flex-grow: 1;
flex-shrink: 0;
flex-basis: 35%;
min-width: 300px;
}
.container>.left>.blocks {
display: flex;
flex-direction: column;
width: 100%;
}
.container>.left>h4 {
font-family: 'Roboto';
font-weight: bold;
margin: 10px auto;
font-size: 18px;
text-align: center;
}
.container>.left>.blocks>.block {
width: 100%;
padding: 10px 15px;
margin-top: 5px;
border: 1px solid rgba(0, 0, 0, 0.2);
cursor: move;
}
.block.dragging {
opacity: .5;
}
.container>.right {
width: 100%;
height: 100%;
border: 1px solid rgba(0, 0, 0, 0.2);
flex-grow: 0;
flex-shrink: 1;
overflow-x: auto;
}
.container>.handle {
background-color: rgba(0, 0, 0, 0.4);
content: '';
width: 7px;
cursor: col-resize;
flex-grow: 0;
flex-shrink: 0;
margin: 0 0 0 auto;
}<div class = "container">
<div class = "left">
<h4>Blocks</h4>
<div class = "blocks" id = "blocks">
<div draggable = "true" class = "block" data-block = "1">Test Block 1 H1</div>
<div draggable = "true" class = "block" data-block = "2">Test Block 1 H2</div>
<div draggable = "true" class = "block" data-block = "3">Test Block 1 H3</div>
<div draggable = "true" class = "block" data-block = "4">Test Block 1 button</div>
</div>
</div>
<div class = "handle" id = "handle"></div>
<div class = "right"></div>
</div>Можете ли вы быть более конкретным, так как это работает на фрагменте.
Да, это работает на фрагменте, но когда я пытаюсь запустить на локальном компьютере, возникает ошибка.
Можете ли вы дать мне строку, которая вызывает эту ошибку.
этот -> handle.draggable = true;
Вам не хватает html-элемента с классом "handle".
Наличие элемента HTML с классом «дескриптор»
Что ж, эта строка выдает ошибку «Невозможно установить свойства нуля», что означает, что она не может найти дескриптор константы в DOM. Таким образом, у вас либо нет элемента с идентификатором «дескриптор», либо вы пытаетесь найти элемент с другим идентификатором. Это все, что я могу сделать, пока вы не опубликуете код, с которым работаете. Если это все еще не решит вашу проблему, дайте мне ссылку js.fiddle или codepen с вашим кодом.
Проверил еще раз, теперь работает нормально. Спасибо за своевременную помощь!!!
Получение этой ошибки -> Uncaught TypeError: невозможно установить свойства null (настройка «перетаскиваемый»)