JavaScript How to Dynamically Move Div by Clicking and Dragging
Check if this is smoother than adeneo: FIDDLE
var m = document.getElementById('move');
m.addEventListener('mousedown', mouseDown, false);
window.addEventListener('mouseup', mouseUp, false);
function mouseUp() {
window.removeEventListener('mousemove', move, true);
}
function mouseDown(e) {
window.addEventListener('mousemove', move, true);
}
function move(e) {
m.style.top = e.clientY + 'px';
m.style.left = e.clientX + 'px';
};
I think you're looking for something more like this
var mousePosition;
var offset = [0,0];
var div;
var isDown = false;
div = document.createElement("div");
div.style.position = "absolute";
div.style.left = "0px";
div.style.top = "0px";
div.style.width = "100px";
div.style.height = "100px";
div.style.background = "red";
div.style.color = "blue";
document.body.appendChild(div);
div.addEventListener('mousedown', function(e) {
isDown = true;
offset = [
div.offsetLeft - e.clientX,
div.offsetTop - e.clientY
];
}, true);
document.addEventListener('mouseup', function() {
isDown = false;
}, true);
document.addEventListener('mousemove', function(event) {
event.preventDefault();
if (isDown) {
mousePosition = {
x : event.clientX,
y : event.clientY
};
div.style.left = (mousePosition.x + offset[0]) + 'px';
div.style.top = (mousePosition.y + offset[1]) + 'px';
}
}, true);
FIDDLE
Support for touch inputs
All other answers (including the accepted one) do not work with touch inputs. Touch inputs have events different than that of mouse inputs. See Using Touch Events on MDN.
The following code snippet works even with touch inputs. I have highlighted all lines of code that need to be added to support touch devices.
The basic idea here is that every element containing draggable
in the class list should be draggable. This concept is easier to follow when you have a big number of elements that need to be dragged.
See this Glitch page and following for a demo.
const d = document.getElementsByClassName("draggable");
for (let i = 0; i < d.length; i++) {
d[i].style.position = "relative";
}
function filter(e) {
let target = e.target;
if (!target.classList.contains("draggable")) {
return;
}
target.moving = true;
//NOTICE THIS ð Check if Mouse events exist on users' device
if (e.clientX) {
target.oldX = e.clientX; // If they exist then use Mouse input
target.oldY = e.clientY;
} else {
target.oldX = e.touches[0].clientX; // Otherwise use touch input
target.oldY = e.touches[0].clientY;
}
//NOTICE THIS ð Since there can be multiple touches, you need to mention which touch to look for, we are using the first touch only in this case
target.oldLeft = window.getComputedStyle(target).getPropertyValue('left').split('px')[0] * 1;
target.oldTop = window.getComputedStyle(target).getPropertyValue('top').split('px')[0] * 1;
document.onmousemove = dr;
//NOTICE THIS ð
document.ontouchmove = dr;
//NOTICE THIS ð
function dr(event) {
event.preventDefault();
if (!target.moving) {
return;
}
//NOTICE THIS ð
if (event.clientX) {
target.distX = event.clientX - target.oldX;
target.distY = event.clientY - target.oldY;
} else {
target.distX = event.touches[0].clientX - target.oldX;
target.distY = event.touches[0].clientY - target.oldY;
}
//NOTICE THIS ð
target.style.left = target.oldLeft + target.distX + "px";
target.style.top = target.oldTop + target.distY + "px";
}
function endDrag() {
target.moving = false;
}
target.onmouseup = endDrag;
//NOTICE THIS ð
target.ontouchend = endDrag;
//NOTICE THIS ð
}
document.onmousedown = filter;
//NOTICE THIS ð
document.ontouchstart = filter;
//NOTICE THIS ð
.draggable {
width: 100px;
height: 100px;
background: red;
}
<div class="draggable"></div>