treehouse : what would you like to learn today?
Web Design Web Development iOS Development

Draggable without jQuery UI

Last updated on:

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

View Comments

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?

  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?

    • Dan
      Permalink to comment#

      Is not a bug. Remove set css z-index.
      $drag.css(‘z-index’, 1000)

  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.

Leave a Comment

Use markdown or basic HTML and be nice.