An alternative, using only CSS, is to style the :active
pseudo-class of the element to the desired drag style. The dragged copy will be created based on this state.
However, the original element will be kept with this style, as the browser seems to keep it :active
until drop.
To avoid this we can assign the style in an animation that runs for a very short period of time. Enough for the browser to copy the style but not too short. 0.1s seems enough for Chrome, Safari and Firefox.
https://jsfiddle.net/mLsw5ajr/
$('#draggable').bind('dragstart', function(e) {
// https://mcmap.net/q/53766/-get-selected-element-39-s-outer-html
var stuff = $(this).clone().wrap('<div></div>').parent().html();
e.originalEvent.dataTransfer.effectAllowed = 'copy';
e.originalEvent.dataTransfer.setData('stuff', stuff);
});
$('#draggable').bind('drag', function(e) {
// here I want to style the ghost element, not the source...
});
$('#droppable').bind('dragover', function(e) {
if (e.originalEvent.preventDefault)
e.preventDefault();
e.originalEvent.dataTransfer.dropEffect = 'copy';
return false;
});
$('#droppable').bind('dragenter', function(e) {
$(this).addClass('over');
});
$('#droppable').bind('dragleave', function(e) {
$(this).removeClass('over');
});
$('#droppable').bind('drop', function(e) {
if (e.originalEvent.stopPropagation)
e.originalEvent.stopPropagation();
var stuff = $(e.originalEvent.dataTransfer.getData('stuff'));
stuff.appendTo(this);
return false;
});
#draggable,
#droppable {
background: #ccc;
color: #fff;
padding: 10px;
margin: 10px 0 100px;
}
#draggable:active {
animation: drag_style .1s;
}
#droppable.over {
background: #000;
}
@keyframes drag_style {
0% {
background-color: #fc0;
color: #000;
}
99% {
background-color: #fc0;
color: #000;
}
100% {
background-color: #ccc;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="draggable" draggable="true">
<p>Drag me to my target</p>
</div>
<div id="droppable">
<p>Drop me</p>
</div>
A problem I found in Firefox is that the element is kept :active
if there is no event triggering by another element (like a drop). To fix this we could trigger a click outside the element.