Reputation: 97
I feel like this should be really simple. I wrote a codepen for it, just to talk out the problem https://codepen.io/rubixKube/pen/yPXPzr.
I am trying to remove the parent node (span) without removing the thing I just dropped it into.
Just wondering if someone out there has a better idea of how to do this.
I've tried this on my onmouse event:
//capturing the elements in variables
var mytarget = event.target;
var mytargetsibling = event.target.previousElementSibling;
//next three lines are just how drag and drop works
event.preventDefault();
var data = event.dataTransfer.getData("text");
event.target.appendChild(document.getElementById(data));
//trying to remove it AND then put the child back
this.parentNode.remove(this);
mytargetsibling.appendChild(mytarget);
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
.tags {
padding: 6px;
}
.drop-area {
border: 1px solid red;
}
.drag-this {
background: blue;
color: white;
}
<ul>
<li>
<span class="header tags">Apple</span>
<span class="drop-area target-drop tags" ondrop="drop(event)" ondragover="allowDrop(event)">Drop HERE</span>
</li>
</ul>
<ul>
<li><span id="drag1" class="drag-this tags" draggable="true" ondragstart="drag(event)">Apple</span></li>
</ul>
Upvotes: 1
Views: 1263
Reputation: 253308
I'd suggest that, rather than event.target.appendChild()
you use instead: event.target.parentNode.replaceChild(newElement, event.target)
which will, as the method-name suggests, replace the existing child (event.target
) with the new child (newElement
):
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text"),
// cached as a variable to simplify the later
// code for readability:
elToAdd = document.getElementById(data),
// we're accessing this node twice, so caching it here:
dropBefore = ev.target;
// moving from the dropBefore node to its parentNode,
// and calling the replaceChild() method to insert
// 'elToAdd' in place of the existing 'dropBefore' node:
dropBefore.parentNode.replaceChild(elToAdd, dropBefore);
}
.tags {
padding: 6px;
}
.drop-area {
border: 1px solid red;
}
.drag-this {
background: blue;
color: white;
}
<ul>
<li>
<span class="header tags">Apple</span>
<span class="drop-area target-drop tags" ondrop="drop(event)" ondragover="allowDrop(event)">Drop HERE</span>
</li>
</ul>
<ul>
<li><span id="drag1" class="drag-this tags" draggable="true" ondragstart="drag(event)">Apple</span></li>
</ul>
Or, instead, you could use Node.replaceWith()
:
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text"),
// caching as variables to simplify the later
// code for readability:
elToAdd = document.getElementById(data),
dropBefore = ev.target;
// using childNode.replaceWith() to insert the
// elToAdd Node in place of the existing
// dropBefore Node:
dropBefore.replaceWith(elToAdd);
}
.tags {
padding: 6px;
}
.drop-area {
border: 1px solid red;
}
.drag-this {
background: blue;
color: white;
}
<ul>
<li>
<span class="header tags">Apple</span>
<span class="drop-area target-drop tags" ondrop="drop(event)" ondragover="allowDrop(event)">Drop HERE</span>
</li>
</ul>
<ul>
<li><span id="drag1" class="drag-this tags" draggable="true" ondragstart="drag(event)">Apple</span></li>
</ul>
References:
Upvotes: 1