HTML5 Drag and Copy

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



Leave a reply



Submit