About

I wrote this JQuery-Only Drag&Drop snippet due to the fact that I was looking for something like this, but I couldn’t find anything that suited my needs. I’m currently writing a plugin where I need this anyway so I thought I’d create my own.

My method uses CSS transform if possible, if not it uses just the standard top and left values like jQuery UI’s .draggable() method. Works in all major browsers and down to IE7 (Emulated with IE10).

Check out the demo and the download-link above.

The Code

(function($, window, document, undefined){
    $.fn.draggit = function(){
         //declare handle and positioning objects
          var el = this,
                dragging = false;

                //container element mustn't be set to position static in order for position caching to work properly
                el.parent().css('position', 'relative');

                //cache position values adjacent to [X-Axis, Y-Axis]
                el.cacheVal = [el.position().left, el.position().top];
                //set object properties to work with later
                el.offsetLeft = el.cacheVal[0];
                el.offsetTop = el.cacheVal[1];

                //check if CSS transform is availiable
            var supports = (function() {  
          var div = document.createElement('div'),  
             vendors = 'Khtml Ms O Moz Webkit'.split(' '),  
             len = vendors.length;  

          return function(prop) {  
              if ( prop in div.style ) return true;  

             prop = prop.replace(/^[a-z]/, function(val) {  
                return val.toUpperCase();  
              });  

             while(len--) {  
                 if ( vendors[len] + prop in div.style ) {  
                    return true;  
                 }   
             }  
             return false;  
          };  
       })();

       //create variable for checking compatibility
      var supportsTransform = supports('transform');

      if(supportsTransform){
          // reset css values to 0 for transform is gonna to the job
                el[0].style.top = 0;
          el[0].style.left = 0;
         // keep the element on the same position tough
          el.css('transform', 'matrix(1, 0, 0, 1, '+el.cacheVal[0]+', '+el.cacheVal[1]+')');
      }

         el.on('mousedown', function(e) {
              //set property equal to cursor position on the screen
             el.cursorX = e.pageX;
             el.cursorY = e.pageY;
             //user starts to drag
             dragging = true;
              // disable selection
              e.preventDefault();
                //if user is moving execute the following
                el.parents().on('mousemove', function(e) {
                    //only if the user is currently dragging, execute the following
                    if(dragging === true) {
                        //provide value for styling
                        el.offsetLeft = el.cacheVal[0] + e.pageX - el.cursorX;
                        el.offsetTop = el.cacheVal[1] + e.pageY - el.cursorY;
                        //style it
                        if(supportsTransform == true) {
                            //using jQuery's .css() method for automatic prefixing
                            el.css('transform', 'matrix(1, 0, 0, 1, '+el.offsetLeft+', '+el.offsetTop+')');
                        } else {
                            //using plain JavaScript for better preformance
                            el[0].style.left = el.offsetLeft+"px";
                            el[0].style.top = el.offsetTop+"px";
                        }
                    }
                });

         }).on('mouseup', function() {
           //user stopped dragging
       dragging = false;
       //cache the offset values in order to prevent the element from returning to 0
       el.cacheVal[0] = el.offsetLeft;
       el.cacheVal[1] = el.offsetTop;
                //stop listening
                el.parents().off('mousemove');
          });
         //allow chaining by returning the jQuery object
         return el;
    }
})( jQuery, window, document );

More on this