HTML5 drag and copy?
I will stick to the example shown here: http://www.w3schools.com/html/html5_draganddrop.asp
Assuming we have this document:
<!DOCTYPE HTML>
<html>
<head>
<script>
<!-- script comes in the text below -->
</script>
</head>
<body>
<div id="div1" ondrop="drop(event)"
ondragover="allowDrop(event)"></div>
<img id="drag1" src="img_logo.gif" draggable="true"
ondragstart="drag(event)" width="336" height="69">
</body>
</html>
Normal Drag & Drop
Normal drag and drop has such functions assigned to the respective elements:
function allowDrop(ev) {
/* The default handling is to not allow dropping elements. */
/* Here we allow it by preventing the default behaviour. */
ev.preventDefault();
}
function drag(ev) {
/* Here is specified what should be dragged. */
/* This data will be dropped at the place where the mouse button is released */
/* Here, we want to drag the element itself, so we set it's ID. */
ev.dataTransfer.setData("text/html", ev.target.id);
}
function drop(ev) {
/* The default handling is not to process a drop action and hand it to the next
higher html element in your DOM. */
/* Here, we prevent the default behaviour in order to process the event within
this handler and to stop further propagation of the event. */
ev.preventDefault();
/* In the drag event, we set the *variable* (it is not a variable name but a
format, please check the reference!) "text/html", now we read it out */
var data=ev.dataTransfer.getData("text/html");
/* As we put the ID of the source element into this variable, we can now use
this ID to manipulate the dragged element as we wish. */
/* Let's just move it through the DOM and append it here */
ev.target.appendChild(document.getElementById(data));
}
Drag & Copy
Whereas you'll have to alter the drop function so that it copies the DOM element instead of moving it.
/* other functions stay the same */
function drop(ev) {
ev.preventDefault();
var data=ev.dataTransfer.getData("text/html");
/* If you use DOM manipulation functions, their default behaviour it not to
copy but to alter and move elements. By appending a ".cloneNode(true)",
you will not move the original element, but create a copy. */
var nodeCopy = document.getElementById(data).cloneNode(true);
nodeCopy.id = "newId"; /* We cannot use the same ID */
ev.target.appendChild(nodeCopy);
}
Try this page: http://www.w3schools.com/html/tryit.asp?filename=tryhtml5_draganddrop
And then append a .cloneNode(true)
to getElementById(data)
.
Switch between Copy & Paste
You could even do things like in file managers: Ctrl-Key switches from moving to copying:
function drop(ev) {
ev.preventDefault();
var data=ev.dataTransfer.getData("text/html");
/* Within a Mouse event you can even check the status of some Keyboard-Buttons
such as CTRL, ALT, SHIFT. */
if (ev.ctrlKey)
{
var nodeCopy = document.getElementById(data).cloneNode(true);
nodeCopy.id = "newId"; /* We cannot use the same ID */
ev.target.appendChild(nodeCopy);
}
else
ev.target.appendChild(document.getElementById(data));
}
HTML5 Drag and Drop issue with Cloning and replacing
I have modified your function slighlty to update node id
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
var isLeft = 'drag1' == data || "drag2" == data;
var nodeCopy = document.getElementById(data).cloneNode(true);
nodeCopy.id = "img" + ev.target.id;
if (!isLeft) {
sourceNode = document.getElementById(data);
sourceNode.parentNode.removeChild(sourceNode);
}
ev.target.appendChild(nodeCopy);
ev.stopPropagation();
return false;
}
See DEMO
Drag and Drop ( Copy ) in another Div is lining up
On the drop event you get the x and y coords of the mouse and set the style to be absolute in that position. Note that the top left corner of the image will snap to the exact coord of the mouse pointer. See below:
///Drag'n Drop functionsfunction allowDrop(ev) { ev.preventDefault();}
function drag(ev) { ev.dataTransfer.setData("text", ev.target.id); ev.dataTransfer.effectAllowed = "copy";}
function drop(ev) { ev.preventDefault(); var x = ev.clientX; var y = ev.clientY; var data = ev.dataTransfer.getData("text"); var copyimg = document.createElement("img"); var original = document.getElementById(data); copyimg.src = original.src; ev.target.appendChild(copyimg); copyimg.setAttribute("style", "position: absolute; top: "+y+"px; left:"+x+"px;");}
#conteudo-left{ width:150px; height:330px; float:left; background-color:#FFF;}
#conteudo{ width:300px; height:250px; float:left; background-color:#ff1; display: initial; margin: auto; box-sizing: border-box;
}
<html> <head> <link type="text/css" rel="stylesheet" media="screen" href="css/testednd.css" /> <!-- CSS das div's --> <script src="js/testednd.js"></script> <!-- Script clickImagem --> </head> <body> <div id="conteudo-left" style="position:static; left:10px; top:20px; width:300; height:660; z-index:-1; overflow: auto"> <form name="form_dnd_left" border = 1> <ul> <li><img id="drag1" src="http://via.placeholder.com/50x50" draggable="true" ondragstart="drag(event)" alt="asdfasdf" /></li> </ul> </form> </div> <div class="conteudo" id="conteudo" ondrop="drop(event)" ondragover="allowDrop(event)"> </div> </body></html>
HTML5 Drag & Drop and touching text
The problem is that the text constitutes an extra node in the DOM, and dragleave
and dragenter
take into account child elements as well as parent elements. When the cursor enters the text node, it leaves the div
. This is similar to the mouseout
vs mouseleave
issue. A simple way to work around it is to keep a count of the events and only remove the style when all are accounted for:
var count=0;
$("div.target").on('dragenter', function(e) {
$(this).addClass('over');
count++;
}).on('dragleave', function(e) {
if (--count<=0) {
$(this).removeClass('over');
}
});
This isn't necessarily completely reliable (remember to set count
to zero in the drop
event), but it'll work better than your current setup. Another option is to not put any content in the div
elements at all, instead add it with CSS:
.target:after {
content: 'I am a target \A Touch text while dragging to see the problem';
white-space: pre-wrap;
}
This has some accessibility drawbacks, because generated content is invisible to assistive technology, and will only let you add text, but is in many ways a cleaner solution.
HTML5 Drag-and-Drop: How do I target the cloned AND original elements?
I am not an avid JavaScript scripter, but i stumbled upon this page while trying to find something for you, it might be what you need, specifically the proxy drag version:
http://threedubmedia.com/demo/drag/
$('#demo6_box')
.bind('dragstart',function( event ){
if ( !$(event.target).is('.handle') ) return false;
return $( this ).css('opacity',.5)
.clone().addClass('active')
.insertAfter( this );
})
.bind('drag',function( event ){
$( event.dragProxy ).css({
top: event.offsetY,
left: event.offsetX
});
})
.bind('dragend',function( event ){
$( event.dragProxy ).remove();
$( this ).animate({
top: event.offsetY,
left: event.offsetX,
opacity: 1
})
});
This is all jQuery.
Related Topics
Is Any Way That Is Safe to Display Videos in a Browser
How to Make a HTML Page to Show Content from Another Url
Text Gradient with Font Awesome
How to Change Border Color of Textarea on: Focus
Zoom Changes The Design Layout
How to Upload Multiple Files Using One File Input Element
Height Is Not Correct in Flexbox Items in Chrome
Bootstrap Row and Col Explanation
How to Make Bootstrap 4 Columns All The Same Height
CSS/HTML: Create a Glowing Border Around an Input Field
In Chrome 55, Prevent Showing Download Button for HTML 5 Video
Websocket Server Implementations for Delphi