Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a draggable div in native javascript [duplicate]

Tags:

javascript

I want to create a movable/draggable div in native javascript without using jquery and libraries. Is there a tutorial or anythign?

like image 781
amit Avatar asked Oct 31 '12 06:10

amit


People also ask

How do I make a div element draggable?

To make an object draggable set draggable=true on that element. Just about anything can be drag-enabled: images, files, links, files, or any markup on your page.

How do you make something draggable in Javascript?

Add the draggable property with the value of true to an element to make it draggable. The dragstart , drag , and dragend events fire on the draggable element. The dragenter , dragover , dragleave or drop events fire on the drop target.

How do you make multiple draggable HTML elements?

dragElement(document. getElementById("mydiv")) in this case here, elmnt would be the Element returned by getElementById. In our example, we're trying to do multiple at the same time, so we first get a list of the elements that have the mydiv class. Then we need to bind each and every one of them with on click handlers.


1 Answers

OK, here's my personal code that I use for lightweight deployments (projects where using a library is either not allowed or overkill for some reason). First thing first, I always use this convenience function so that I can pass either an id or the actual dom element:

function get (el) {
  if (typeof el == 'string') return document.getElementById(el);
  return el;
}

As a bonus, get() is shorter to type than document.getElementById() and my code ends up shorter.

Second realize that what most libraries are doing is cross-browser compatibility. If all browsers behave the same the code is fairly trivial. So lets write some cross-browser functions to get mouse position:

function mouseX (e) {
  if (e.pageX) {
    return e.pageX;
  }
  if (e.clientX) {
    return e.clientX + (document.documentElement.scrollLeft ?
      document.documentElement.scrollLeft :
      document.body.scrollLeft);
  }
  return null;
}

function mouseY (e) {
  if (e.pageY) {
    return e.pageY;
  }
  if (e.clientY) {
    return e.clientY + (document.documentElement.scrollTop ?
      document.documentElement.scrollTop :
      document.body.scrollTop);
  }
  return null;
}

OK, the two functions above are identical. There're certainly better ways to write them but I'm keeping it (relatively) simple for now.

Now we can write the drag and drop code. The thing I like about this code is that everything's captured in a single closure so there are no global variables or helper functions littering the browser. Also, the code separates the drag handle from the object being dragged. This is useful for creating dialog boxes etc. But if not needed, you can always assign them the same object. Anyway, here's the code:

function dragable (clickEl,dragEl) {
  var p = get(clickEl);
  var t = get(dragEl);
  var drag = false;
  offsetX = 0;
  offsetY = 0;
  var mousemoveTemp = null;

  if (t) {
    var move = function (x,y) {
      t.style.left = (parseInt(t.style.left)+x) + "px";
      t.style.top  = (parseInt(t.style.top) +y) + "px";
    }
    var mouseMoveHandler = function (e) {
      e = e || window.event;

      if(!drag){return true};

      var x = mouseX(e);
      var y = mouseY(e);
      if (x != offsetX || y != offsetY) {
        move(x-offsetX,y-offsetY);
        offsetX = x;
        offsetY = y;
      }
      return false;
    }
    var start_drag = function (e) {
      e = e || window.event;

      offsetX=mouseX(e);
      offsetY=mouseY(e);
      drag=true; // basically we're using this to detect dragging

      // save any previous mousemove event handler:
      if (document.body.onmousemove) {
        mousemoveTemp = document.body.onmousemove;
      }
      document.body.onmousemove = mouseMoveHandler;
      return false;
    }
    var stop_drag = function () {
      drag=false;      

      // restore previous mousemove event handler if necessary:
      if (mousemoveTemp) {
        document.body.onmousemove = mousemoveTemp;
        mousemoveTemp = null;
      }
      return false;
    }
    p.onmousedown = start_drag;
    p.onmouseup = stop_drag;
  }
}

There is a reason for the slightly convoluted offsetX/offsetY calculations. If you notice, it's just taking the difference between mouse positions and adding them back to the position of the div being dragged. Why not just use the mouse positions? Well, if you do that the div will jump to the mouse pointer when you click on it. Which is a behavior I did not want.

like image 200
slebetman Avatar answered Sep 22 '22 07:09

slebetman