Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript How to Dynamically Move Div by Clicking and Dragging

Okay it would seem like it should be simple. I need to take an already existing div and move it according to mouse position within the window. I have searched everywhere and it has led me to over-complicated ways of doing the same thing and involves the use of j-query. I need to strictly use javascript for what I am trying to do.

Method :

var mousePosition; var div;  (function createDiv(){      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";      div.addEventListener('mousedown', handleKeyPressed, true);      document.body.appendChild(div);   })();  function handleKeyPressed(event) {      event.preventDefault();      mousePosition = {          x : event.clientX,         y : event.clientY      };      div.style.left = mousePosition.x;     div.style.top = mousePosition.y;      //alert("whoa!");  } 
like image 643
StoneAgeCoder Avatar asked Jun 05 '14 02:06

StoneAgeCoder


People also ask

How do you drag an element in JavaScript?

Introduction to JavaScript Drag and Drop API To drag an image, you simply hold the mouse button down and then move it. To drag the text, you need to highlight some text and drag it in the same way as you would drag an image.


2 Answers

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

like image 161
adeneo Avatar answered Sep 21 '22 14:09

adeneo


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>
like image 29
mmaismma Avatar answered Sep 23 '22 14:09

mmaismma