EN
JavaScript - how to make drag and drop div with handle?
4
points
Using JavaScript it is possible to make drag&drop div element with handle in the following way.
Practical example
Note: big advantage of presented approach in this section is resistance for changed margin, border and padding sizes (with nested elements too).
More complicated example with nexted elements is here.
// ONLINE-RUNNER:browser;
<!doctype html>
<html>
<head>
<style>
div.draggable {
position: absolute;
left: 20px; right: 20px;
border: 5px solid gray;
}
div.handle {
padding: 3px;
position: absolute;
left: 0; top: 0; right: 0;
background: gold;
height: 25px;
}
div.body {
padding: 3px;
position: absolute;
left: 0; top: 25px; right: 0; bottom: 0;
background: cyan;
}
* { /* this style disables selection for all elements on web page */
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox in the past (old versions) */
-ms-user-select: none; /* Internet Explorer (>=10) / Edge */
user-select: none; /* Currently supported: */
/* Chrome, Opera and Firefox */
}
</style>
<script type="text/javascript">
function getMargins(element) {
var style = element.currentStyle || window.getComputedStyle(element);
var result = {
getX: function() {
return parseInt(style.marginLeft);
},
getY: function() {
return parseInt(style.marginTop);
}
};
return result;
}
function prepareDragging(element, handle) {
var dragging = false;
var clickX, clickY;
var positionX, positionY;
var style = element.style;
function onMouseDown(e) {
clickX = e.clientX;
clickY = e.clientY;
var margins = getMargins(element); // prevents against different margin sizes
positionX = element.offsetLeft - margins.getX();
positionY = element.offsetTop - margins.getY();
dragging = true;
}
function onMouseUp(e) {
dragging = false;
}
function onMouseMove(e) {
if (dragging) {
var x = positionX + e.clientX - clickX;
var y = positionY + e.clientY - clickY;
style.left = x + 'px';
style.top = y + 'px';
}
}
handle.addEventListener('mousedown', onMouseDown);
window.addEventListener('mouseup', onMouseUp);
window.addEventListener('mousemove', onMouseMove);
var remove = function() {
if (remove) {
handle.removeEventListener('mousedown', onMouseDown);
window.removeEventListener('mouseup', onMouseUp);
window.removeEventListener('mousemove', onMouseMove);
remove = null;
}
};
return remove;
}
</script>
</head>
<body style="height: 200px;">
<div id="my-element" class="draggable" style="width: 130px; height: 130px;">
<div id="my-handle" class="handle">Drag me...</div>
<div class="body">Something inside...</div>
</div>
<script>
var element = document.querySelector('#my-element');
var handle = document.querySelector('#my-handle');
prepareDragging(element, handle);
</script>
</body>
</html>