Grow your CSS skills. Land your dream job.

Last updated on:

Draggable without jQuery UI

It doesn't have all the fancy callbacks and options, but hey, it makes things draggable (and with a specified handle optionally).

(function($) {
    $.fn.drags = function(opt) {

        opt = $.extend({handle:"",cursor:"move"}, opt);

        if(opt.handle === "") {
            var $el = this;
        } else {
            var $el = this.find(opt.handle);
        }

        return $el.css('cursor', opt.cursor).on("mousedown", function(e) {
            if(opt.handle === "") {
                var $drag = $(this).addClass('draggable');
            } else {
                var $drag = $(this).addClass('active-handle').parent().addClass('draggable');
            }
            var z_idx = $drag.css('z-index'),
                drg_h = $drag.outerHeight(),
                drg_w = $drag.outerWidth(),
                pos_y = $drag.offset().top + drg_h - e.pageY,
                pos_x = $drag.offset().left + drg_w - e.pageX;
            $drag.css('z-index', 1000).parents().on("mousemove", function(e) {
                $('.draggable').offset({
                    top:e.pageY + pos_y - drg_h,
                    left:e.pageX + pos_x - drg_w
                }).on("mouseup", function() {
                    $(this).removeClass('draggable').css('z-index', z_idx);
                });
            });
            e.preventDefault(); // disable selection
        }).on("mouseup", function() {
            if(opt.handle === "") {
                $(this).removeClass('draggable');
            } else {
                $(this).removeClass('active-handle').parent().removeClass('draggable');
            }
        });

    }
})(jQuery);

Usage

$('div').drags();

Demo

Reference URL

Comments

  1. I didn’t realize you could drop code pens in pages. That is a really nice feature. Sorry to distract from the point of this post.

  2. Good works so far.

  3. I just wanted to request this, thanks.

    (Btw i would move “var $el” and “var $drag” up a few lines, so “var” is only there once, and JSHint won’t cry… maybe the handle could be also deeper in the draggable object, .parent() won’t do it? )

  4. Omer S.
    Permalink to comment#

    quick & light-weighted alternative to Jquery UI’s draggable!!!!

  5. Permalink to comment#

    Oh thank you, was always trying to find a simple script like that… which is NOT buggy :) now adding some onDragEnd and onDragStart is very simple in this case

  6. max
    Permalink to comment#

    hmm it kills
    select

    elemets inside a draggable parent container, the options don’t show up anymore if you click that little triangle :/ However buttons, checkboxes and radiobuttons still work fine.

  7. Michael A.
    Permalink to comment#

    How would I get this to work on touch-based devices?

    • SKR
      Permalink to comment#

      Hey! Did you find any solution?
      Thanks in advance! :D

    • billy
      Permalink to comment#

      ya i’m also looking for a solution to touch screen draggable. ui-draggable breaks when transform is being used on the element : \

    • Grant McLean
      Permalink to comment#

      In response to people asking about touch support, you might be interested in this simple draggable plugin I’ve made that works with touch and mouse events: https://github.com/grantm/jquery-udraggable/

      The touch support comes courtesy of Michael S. Mikowski’s jquery.event.ue plugin.

  8. Aurel
    Permalink to comment#

    There is a little bug … If there are two draggable items on the same page, the first time when you click on one of them, the other one moves over it . That happens just at the first click, then everything works just fine as it should … Can anyone tell me how could I fix that?

  9. Aurel
    Permalink to comment#

    I’ve solved it, was my mistake, instead of using ids for every draggable item, I set the plugin for a class, and I called it “draggable”, didn’t know that the plugin needs that class to activate/disable the moving on mousedown/mouseup. Sorry, I forgot to comment again how the problem was solved. This is really a good plugin. Is there a way to add a new option to this plugin, to set a button or something, and to be able to move the item just from that button? I have a “draggable panel” with dynamic content, and sometimes needs a vertical scrollbar and when you move the scrollbar moves the panel too. For now I’ve solved the problem by adding a button “Activate/Disable Draggable”

  10. hays
    Permalink to comment#

    got an error “TypeError: $el.css(“cursor”, opt.cursor).on is not a function”

  11. Permalink to comment#

    Draggables are great fun. I’ve had quite a bit of fun with them – http://grafiks101.com . Now that, ’tis the season’, I would like to see a routine that triggers an action based on drop area. You know, like decorating a Christmas tree, but… if you hang the bulb on the wrong branch, the tree explodes!

    Fun stuff and I can’t tell you how much I have learned from css-tricks.com!!

  12. Viken
    Permalink to comment#

    How should i use handle? I have a popup and i want to make header as a handle and whole popup as draggable.

    • Viken
      Permalink to comment#

      Forgot to mention that I have tried using “$.extend({handle:”.drag_handle”,cursor:”move”}, opt);” but not working.

    • Viken
      Permalink to comment#

      Sorry Guys….it was my mistake. it’s done.

  13. Stefan Gougherty
    Permalink to comment#

    This draggable trick is awesome! Is there a way to include a little button within the draggable object to close it?

    I have “oldschool looking diaolgue boxes” in my website- http://www.stefangougherty.com which are draggable and more importantly closable. Unfortunately the old javascript that enables them conflicted with the !DOCTYPE info in the header, so I had to remove that which was crucial for my site to perform correctly in IE.

    Any advice? (I only know basic html and css but have been pretty successful at ‘reverse engineering’ more complicated stuff)

    thanks!!!

  14. Permalink to comment#

    I get a weird behavior in IExplorer where the cursor changes to then “CAN’t drag here” and the draggin requires me to click away, there will be dragging but with delays.

  15. pike
    Permalink to comment#

    Ehm, dont you have to unbind mousemove somewhere ? once you start dragging, the triggers never stop. the moving stops because the .draggable class is removed, but the triggers keep on firing ?

    *-pike

  16. I really appreciate this code. A few minor criticism / questions…

    why set a class on the dragging item? to highlight while drag?
    why use drg_w, drg_h vars? these can simply be removed with no effect.
    why this blog software dooftastically converts underscores to italics? ;)
    why this blog software dooftastically removes leading dashes?

  17. anony
    Permalink to comment#

    this is awesome! i have a quick question – how can i turn it on and off?
    like in draggable we can do $element.draggable(‘option’,’disabled’,true/false);
    any way to do that over here?

  18. Stiles
    Permalink to comment#

    Does not work with Win8 & IE10!

  19. I came across a problem with this script: try logging something from inside the mouseup function on line 28 and you will see that because the mouseup listener is called inside the mousedown function (line 12), the specific function will not only be called every time the mousemove event (line 23) is triggered but multiplied by every time the mousedown event (line 12) is triggered. This can result in some serious preformance issues after the 4th to 5th time you dragged the box somewhere.
    I wrote something similar myself – what do you think of my solution?

  20. Erik

    Sorry if this is waaaaay late (which it is) but I put in all the code identical to how it is here just to try it out and for some reason it did not turn draggable. Is there some bug?

  21. Just what i needed, thanks so much Chris.

  22. Philipp

    Amazing!

  23. rag

    Hey great work!! But can u give me the explanation for this or do u have any documentation regarding this work i m eager to know this, as i m novice to javascript that why asking for all this.

  24. SKR
    Permalink to comment#

    This is good! Works perfectly fine in Chrome browser. But, how can it be modified to work for touch based devices?

  25. Thomas
    Permalink to comment#

    Is there a way of this working behind a div element?

  26. Hooman

    Hey chris I’m a huge fan of your tricks. I have 2 DIVs nesting next to each other with same height and width and there is a border between them can u give me a tip how to make that border draggable so the width of each one will change when we drag that border I mean 50% 50% drag the border to the right and for example width changes to 30% 70%

  27. Arthur Clemens
    Permalink to comment#

    The mousemove events keep firing. You need to trigger mouseup using the window object. Just before $drag....parents().on('mousemove', ... write:

    $(window).one('mouseup', function(e) {
        if (opt.handle === '') {
            $drag.removeClass('draggable');
        } else {
            $drag.removeClass('active-handle').parent().removeClass('draggable');
        }
        $(window).unbind('mouseup');
        $drag.parents().unbind('mousemove');
    });
    
  28. Geoffrey Swenson
    Permalink to comment#

    This is what I’ve done to this so far. It probably still has a few mistakes in it, but I like it better for my purposes than the jQuery UI dragger.

    define(function(require, exports, module) {
    (function($) {
    $.fn.drags = function(opt) {

    var originalZ = null,
    thisDrag = this,
    pos = null,
    dragger, $el, $parents;

    function sortConstraint(x) {
    if (x != null) {
    x.sort();
    }
    }

    function startChildEvents(isActive) {

    $this = $(thisDrag);
    var onOff = isActive ? "on" : "off";

    $drag = (opt.handle === "") ?
    $this.toggleClass('draggable', isActive) :
    $this.toggleClass('active-handle', isActive).parent().toggleClass('draggable', isActive);

    if (originalZ == null) { originalZ = $drag.css('z-index'); }

    $parents = $drag.css('z-index', isActive ? 1001 : originalZ).parents();
    $parents[onOff]("mousemove", mouseMove);

    $el[onOff]("mouseup", mouseUp);
    $el.css('cursor', isActive ? opt.cursor : "default");
    }

    function mouseEnd(e) {

    $drag.css('z-index', originalZ);

    startChildEvents(false);

    var movedLeft = (pos.current.left - pos.start.left) < 0;

    if(opt.handle === "") {
    $(this).removeClass('draggable');
    } else {
    $(this).removeClass('active-handle').parent().removeClass('draggable');
    }

    if (opt.autoEnd) {
    dragger.start(false);
    }

    opt.onEndMove({ movedLeft: movedLeft })
    }

    function mouseDown(e) {

    startChildEvents(true);

    pos.current = $drag.offset();
    pos.start = pos.current;
    pos.click = { y: e.pageY, x: e.pageX };

    e.preventDefault(); // disable selection

    }

    function mouseMove(e) {

    var endMove = (opt.xMaxMove != null && Math.abs(pos.current.left - pos.start.left) > opt.xMaxMove);

    pos.current = {
    top: (opt.axis == "x" ? pos.start.top : pos.start.top + e.pageY - pos.click.y),
    left:(opt.axis == "y" ? pos.start.left: pos.start.left + e.pageX - pos.click.x)
    };

    if (opt.xConstrain != null) {
    var xDiff = pos.current.left - pos.reference.left;
    if (xDiff < opt.xConstrain[0]){
    pos.current.left = pos.reference.left + opt.xConstrain[0];
    endMove = true;
    } else if (xDiff > opt.xConstrain[1]) {
    pos.current.left = pos.reference.left + + opt.xConstrain[1];
    endMove = true;
    }
    }

    endMove = (endMove || opt.yMaxMove != null && Math.abs(pos.current.top - pos.start.top) > opt.yMaxMove);

    if (opt.yConstrain != null) {
    var yDiff = pos.current.top - pos.reference.top;
    if (yDiff < opt.yConstrain[0]){
    pos.current.top = pos.reference.top + opt.yConstrain[0];
    endMove = true;
    } else if (yDiff > opt.yConstrain[1]) {
    pos.current.top = pos.reference.top + + opt.yConstrain[1];
    endMove = true;
    }
    }

    $d = $('.draggable');
    if (endMove) { mouseEnd(); } else {
    $d.offset(pos.current);
    }
    }

    function mouseUp(e) {
    $(this).removeClass('draggable').css('z-index', originalZ);
    }

    dragger = {

    start: function(start, newPos) {

    if (pos == null) {
    var cc = $el.offset();
    pos = { start: cc, current: cc, reference: cc };
    }

    if (typeof newPos != "undefined") {
    pos = $.extend(pos, newPos);
    }

    $el[start ? "on" : "off"]("mousedown", mouseDown);

    if (! start) {
    startChildEvents(false);
    }
    }
    }

    opt = $.extend({
    handle:"",
    cursor:"move",
    axis: null,
    autoStart: true,
    autoEnd: false,
    xMaxMove: null,
    yMaxMove: null,
    xConstrain: null,
    yConstrain: null,
    allowDrag: function() { return true; },
    onEndMove: function() {}
    }, opt);

    sortConstraint(opt.xConstrain);
    sortConstraint(opt.yConstrain);

    $el = (opt.handle === "") ? $el = this : this.find(opt.handle);

    $el.dragger = dragger;
    if (opt.autoStart) { dragger.start(true); }
    return $el

    }
    })(jQuery);

    });

  29. Geoffrey Swenson
    Permalink to comment#

    An update to the previous code. This one now can be passed a click event that runs if the mouse drag is just a couple of pixels or less. Both of these use simpler math than the original posted here, but the overall structure is very similar to the original. It has a lot more features than the original as well, but the way that it handles constraints is much easier to deal with than the jqueryUI dragger.

    define(function(require, exports, module) {
        (function($) {
            $.fn.drags = function(opt) {
    
                var originalZ = null,
                    thisDrag = this,
                    pos = null, 
                    isEnabled = true,
                    dragger, $el, $parents;
    
    
                function sortConstraint(x) {
                    if (x != null) {
                        x.sort();
                    }
                }
    
                function toggleChildEvents(isActive) {
    
                    $this = $(thisDrag);
                    var onOff = isActive ? "on" : "off";
    
                    $drag = (opt.handle === "") ? 
                        $this.toggleClass('draggable', isActive) : 
                        $this.toggleClass('active-handle', isActive).parent().toggleClass('draggable', isActive);
    
                    if (originalZ == null) { originalZ = $drag.css('z-index'); }
    
                    $parents = $drag.css('z-index', isActive ? 1001 : originalZ).parents();
                    $parents[onOff]("mousemove", mouseMove);
    
                    $el[onOff]("mouseup", mouseUp);
                    $el.css('cursor', isActive || opt.keepCursorOnEnd ? opt.cursor : "default");
                }
    
                function mouseEnd() {
    
                    $drag.css('z-index', originalZ);
                    toggleChildEvents(false);
    
                    if (isEnabled) {
                        var movedLeft = (pos.current.left - pos.start.left) < 0;
    
                        if(opt.handle === "") {
                            $(this).removeClass('draggable');
                        } else {
                            $(this).removeClass('active-handle').parent().removeClass('draggable');
                        }
    
                        if (opt.autoEnd) {
                            dragger.start(false);
                        }
    
                        opt.onEndMove({ movedLeft: movedLeft }) 
                    }                               
    
                }
    
                function mouseDown(e) {
    
                    if (isEnabled)
                    {
                        toggleChildEvents(true);
                        pos.current = $drag.offset();
                        pos.start = pos.current;
                        pos.click = { y: e.pageY, x: e.pageX };
                    }
                    e.preventDefault();     // disable selection 
                }
    
                function mouseMove(e) {
    
                    pos.current = {
                        top: (opt.axis == "x" ? pos.start.top : pos.start.top + e.pageY - pos.click.y),
                        left:(opt.axis == "y" ? pos.start.left: pos.start.left + e.pageX - pos.click.x)
                    };
    
                    var endMove = (opt.xMaxMove != null &&  Math.abs(pos.current.left - pos.start.left) > opt.xMaxMove);
    
                    if (opt.xConstrain != null) {  
                        var xDiff = pos.current.left - pos.reference.left;                  
                        if (xDiff < opt.xConstrain[0]){
                            pos.current.left = pos.reference.left + opt.xConstrain[0];
                            endMove = true;
                        } else if (xDiff > opt.xConstrain[1]) {
                            pos.current.left = pos.reference.left + + opt.xConstrain[1];
                            endMove = true;
                        }
                    }
    
                    endMove = (endMove || opt.yMaxMove != null && Math.abs(pos.current.top - pos.start.top) > opt.yMaxMove);
    
                    if (opt.yConstrain != null) {
                        var yDiff = pos.current.top - pos.reference.top;
                        if (yDiff < opt.yConstrain[0]){
                            pos.current.top = pos.reference.top + opt.yConstrain[0];
                            endMove = true;
                        } else if (yDiff > opt.yConstrain[1]) {
                            pos.current.top = pos.reference.top + + opt.yConstrain[1];
                            endMove = true;
                        }
                    }
    
                    $d = $('.draggable');
                    if (endMove) { mouseEnd(); } else {
                        $d.offset(pos.current);
                    }
                }
    
                function mouseUp(e) {
    
                    if (opt.onClick != null)
                    {
                        var d = Math.sqrt(Math.pow(pos.current.left - pos.start.left, 2) + Math.pow(pos.current.top - pos.start.top, 2));
                        if (d < 4) {
                            isEnabled = opt.onClick();
                            return;
                        }
                    }
                    $(this).removeClass('draggable').css('z-index', originalZ);
                    mouseEnd();
                }
    
                dragger = {
    
                    start: function(start, newPos) {
    
                        if (pos == null) {
                            var cc = $el.offset();
                            pos = { start: cc, current: cc, reference: cc };
                        }
    
                        if (typeof newPos != "undefined") {
                            pos = $.extend(pos, newPos);
                        }
    
                        $el[start ? "on" : "off"]("mousedown", mouseDown);
                        if (! start) {
                            toggleChildEvents(false);
                        }
                    },
                    setEnabled: function (enabled) {
                        isEnabled = enabled;
                        if (isEnabled) {
                            pos.current = $drag.offset();
                        } else {
                            toggleChildEvents(isEnabled);
                        }
                    }           
                }
    
                opt = $.extend({
                    handle:"",
                    cursor:"move",
                    axis: null,
                    autoStart: true,
                    autoEnd: false,
                    xMaxMove: null,
                    keepCursorOnEnd: false, 
                    yMaxMove: null, 
                    xConstrain: null, 
                    yConstrain: null,
                    onClick: null,
                    onEndMove: function() {}
                }, opt);
    
                sortConstraint(opt.xConstrain);
                sortConstraint(opt.yConstrain);
    
                $el = (opt.handle === "") ? $el = this : this.find(opt.handle);
    
                $el.dragger = dragger;
                if (opt.autoStart) { dragger.start(true); }
                return $el
    
            }
        })(jQuery);
    });
    
  30. Peter
    Permalink to comment#

    There’s an inherent problem with dragging a panel with input[type=range] controls on it, namely, you can’t use the range sliders because the mousedown event will get intercepted and instead the panel will drag. So I wrote a little solution: dragsOff, using JQuery’s hover method.

    $('parent_panel').drags();
    ...
    $('input[type=range]').hover(function()
    {
        $('parent_panel').dragsOff();
    },
    function()
    {
        $('parent_panel').drags();
    });
    

    And of course, dragsOff:

    (function($) 
    {
        $.fn.dragsOff = function(opt) 
        {
            opt = $.extend({handle:"",cursor:"default"}, opt);
    
            if(opt.handle === "") {
             var $el = this;
             $(this).removeClass('draggable');
            } else {
             var $el = this.find(opt.handle);
             $(this).removeClass('active-handle')
                    .parent()
                    .removeClass('draggable');
            }
            return $el.css('cursor', "default")
                .off("mousedown")
                .off("mouseup")
                .off("mousemove");
        }
    })(jQuery);
    
    • Permalink to comment#

      Nice!

    • Permalink to comment#

      Hi there,
      I had the same problem (about the range input) but I didn’t want to use Jquery. What I made is simply to change the draggable attribute on mouse down.

      myRangeInput.addEventListener("mousedown",onRangeMouseDown,false);
      myRangeInput.addEventListener("mouseup",onRangeMouseUp,false);
      

      And then:

      function onSizeRangeMouseDown() {myContainer.setAttribute("draggable", false);}
      function onSizeRangeMouseUp() {myContainer.setAttribute("draggable", true);}
      
  31. Zenfly Media
    Permalink to comment#

    Brilliant! Thank you very much, been looking for this for hours… :)

  32. hanumesh
    Permalink to comment#

    i understand the above code to drag a image , what if i want a video streaming (webrtc client video) to be made draggable

  33. I’ve edited the script to support touch events… not bullet proof I guess, but working for me.

    http://pastebin.com/wVzEqG7i

  34. kram
    Permalink to comment#

    Sir how to disable draggable when selecting texts in input element inside the draggable div? thank you!

  35. Jota
    Permalink to comment#

    How can I specify a handler? I am new in jQuery and I did not understant your explanation. Thanks

  36. Greg Perham
    Permalink to comment#

    I needed to use this on an element with links. In the original, when the drag completes, it follows a link if that’s where the user grabbed to start/end the drag. This version adds just a few lines to prevent following a link if the (accidental) move was very slight. It also enables it to work on elements positioned with bottom or right in their CSS.

    http://codepen.io/swinggraphics/pen/cxmbj

  37. abdul
    Permalink to comment#

    How to add easing for this?

  38. Similanblu
    Permalink to comment#

    This code has a severe performance problem which you can see if you drag the object several times, each time lagging more and more.

    This is due to a new mousemove event handler being bound ‘over the top’ each time the user clicks on the dragged object. If you dragged the object 10 times, there will be 10 redundant mousemove handler tracking the cursor, hence the lag.

    Geoffrey Swenson’s code remedies this problem, as it cleans up the event handler after each time the user stops dragging. I’d recommend anyone to use his snippet instead of the original.

  39. Alex
    Permalink to comment#

    Textarea inside of draggable element becomes uneditable, had to switch back to UI’s draggable().

  40. Tim
    Permalink to comment#

    Is there a way to restrict the draggable element to it’s parent div size?
    So that it cannot be dragged off the screen?

    • jQuery UI can do that. I feel like as soon as you need some fancy extra stuff, you’re better off going with a more robust thing like jQuery UI or Dragabilly than this simple code above.

  41. a
    Permalink to comment#

    So, everytime a “mousedown” event is called it will add an event handler of “mousemove” ?

  42. Tami
    Permalink to comment#

    The code works so fine.. But i just want to add a click event that should be prevented when the element is dragged. Can anyone help me out with a simple solution?

  43. Wing
    Permalink to comment#

    A little optimze, remove useless width and height, better event handler

    // Draggable plugin
    (function($) {
        $.fn.drag = function(options) {
            options = $.extend({
                handle: null,
                cursor: 'move',
                draggingClass: 'dragging'
            }, options);
    
            var $handle = this,
                $drag = this;
    
            if( options.handle ) {
                $handle = $(options.handle);
            }
    
            $handle
                .css('cursor', options.cursor)
                .on("mousedown", function(e) {
                    var x = $drag.offset().left - e.pageX,
                        y = $drag.offset().top - e.pageY,
                        z = $drag.css('z-index');
    
                    $drag.css('z-index', 100000);
    
                    $(document.documentElement)
                        .on('mousemove.drag', function(e) {
                            $drag.offset({
                                left: x + e.pageX,
                                top: y + e.pageY
                            });
                        })
                        .one('mouseup', function() {
                            $(this).off('mousemove.drag');
                            $drag.css('z-index', z);
                        });
    
                    // disable selection
                    e.preventDefault();
                });
        };
    })(jQuery);
    
  44. very well thank you
    I think this will work better and faster than jquery ui

  45. Laszlo
    Permalink to comment#

    This is a great piece of code. Exactly what I needed.

    I’d like to suggest a fix though:
    If the option {handle: ___} is used then it derails the jQuery chaining because it switches over to the handle element, instead of staying on the same element.

    To fix that change this line:
    return $el.css('cursor', opt.cursor).on("mousedown", function(e) {
    to
    $el.css('cursor', opt.cursor).on("mousedown", function(e) {

    and change the end lines to this:

                            });
                        return this;
                    }
            })(jQuery);
    
  46. Haven’t needed anything alike since the DHTML era, and I’m surprised there’s so few lightweight (light–lined) solutions to this. Thanks to Chris and the wonderful commenters, here follows yet another take, based primarily on Wing‘s optimizations but tweaked for multiple elements, as opposed to his original.

    Handler and cursor options have been removed since I saw no purpose for them in my project, but as a bonus it works well with elements with set bottom or right attributes.

    /*--------------------------------------------------------------
    Draggable
    alternative to jQuery UI’s draggable
    based on comments from: http://css-tricks.com/snippets/jquery/draggable-without-jquery-ui/
    --------------------------------------------------------------*/
    (function($) {
        if (!jQuery().draggable) {
            $.fn.draggable = function() {
                this
                    .css('cursor', 'move')
                    .on('mousedown', function(e) {
                        var $dragged = $(this);
    
                        var x = $dragged.offset().left - e.pageX,
                            y = $dragged.offset().top - e.pageY,
                            z = $dragged.css('z-index');
    
    
                        $(window)
                            .on('mousemove.draggable', function(e) {
                                $dragged
                                    .css({'z-index': 999, 'bottom': 'auto', 'right': 'auto'})
                                    .offset({
                                        left: x + e.pageX,
                                        top: y + e.pageY
                                    });
                            })
                            .one('mouseup', function() {
                                $(this).off('mousemove.draggable');
                                $dragged.css('z-index', z);
                            });
    
                        // disable selection
                        e.preventDefault();
                    });
                return this;
            };
        }
    })(jQuery);
    

    also available on Gist: https://gist.github.com/Arty2/11199162
    comments and suggestions are welcome of course

  47. andy

    This demo works great. But when i implement it on my page, when i drag the element, the ghosted drag item is a huge part of the page, not just the LI that’s being dragged. I’ve also noticed that if i have a lot of these draggable items, other functionality on the page (reorderlist) gets really really slow. Any thoughts?? Thanks!

    • andy

      Update-Issue 1 was fixed by removing a child that had an absolute position within the dragged LI.

  48. gokulan

    cannot not work for click function in dragble div areas

  49. Dustin

    This is beautiful. Awesome work

  50. APourhadi

    nice code, thnx alot for share it. one question:
    often, u have a container div and many child div inside it, something like ‘header’,’main’, ‘footer’ and …
    is there a way to drag hole them (container and it’s child) when drag one of them such as ‘header’ div ?

  51. Note that the original code above works great, EXCEPT that each drag you make slows the browser more and more. To fix this add an .off('event') right before each .on call

  52. What would the code be to drag WordPress Posts, Pages and Categories up or down in their lists? I am looking for code to add to a custom functions plugin I am building. (Instead of using an existing plugin it would be nice to get the code needed for this and the CSS as well.)

    One step further (if that is alright).
    Closing a tree branch. If the user has lots of children it would be nice to close a branch to save on the space. For instance having the possibility to close a page branch, categories branch etc.

  53. Dhanesh
    Permalink to comment#

    This piece of code works perfectly for me. I’ve one question.
    Is there any way to work this in a mobile device without using jQuery Mobile ??

  54. Shikkediel
    Permalink to comment#

    Like many before me, I have a take on this as well. With touch support included.
    Even though the structure of the code is very similar, I actually did not notice this post until recently. But it has pushed me over the edge to start learning how to write jQuery library extensions. So far, it’s only a function (not a plugin) :

    Reading the comments, I think Arthur’s tip on unbinding the mousemove was worthwhile so I’ve implemented that as well. For most of the other issues mentioned, I think a solution was added in the script.

    Previously I resorted to the necessary parts of jQuery UI for creating a draggable, combined with Touch Punch in the hope of cross browser compatibility.

Leave a Comment

Posting Code

Markdown is supported in the comment area, so you can write inline code in backticks like `this` or multiline blocks of code in in triple backtick fences like this:

```
<div>Example code</div>
```

You don't need to escape code in backticks, Markdown does that for you. If anything screws up, contact us and we can fix it up for you.

*May or may not contain any actual "CSS" or "Tricks".