Draggabilly Make that shiz draggable

Overview

Draggabilly

Make that shiz draggable

draggabilly.desandro.com

Rad because it supports mouse and touch devices.

Draggabilly v3.0.0

Install

Download

Package managers

Install with npm: npm install draggabilly

Install with Yarn: yarn add draggabilly

CDN

Link directly to draggabilly.pkgd.min.js on unpkg.com.

">
<script src="https://unpkg.com/draggabilly@3/dist/draggabilly.pkgd.min.js">script>

Usage

Initialize Draggabilly as a jQuery plugin

var $draggable = $('.draggable').draggabilly({
  // options...
})

Initialize Draggabilly with vanilla JS

var elem = document.querySelector('.draggable');
var draggie = new Draggabilly( elem, {
  // options...
});

// or pass in selector string as first argument
var draggie = new Draggabilly( '.draggable', {
  // options...
});

// if you have multiple .draggable elements
// get all draggie elements
var draggableElems = document.querySelectorAll('.draggable');
// array of Draggabillies
var draggies = []
// init Draggabillies
for ( var i=0; i < draggableElems.length; i++ ) {
  var draggableElem = draggableElems[i];
  var draggie = new Draggabilly( draggableElem, {
    // options...
  });
  draggies.push( draggie );
}

Classes

  • .is-pointer-down added when the user's pointer (mouse, touch, pointer) first presses down.
  • .is-dragging added when elements starts to drag.

Options

axis

Type: String

Values: 'x' or 'y'

axis: 'x'

Constrains movement to horizontal or vertical axis.

containment

Type: Element, Selector String, or Boolean

containment: '.container'

Contains movement to the bounds of the element. If true, the container will be the parent element.

grid

Type: Array

Values: [ x, y ]

grid: [ 20, 20 ]

Snaps the element to a grid, every x and y pixels.

handle

Type: Selector String, Array, HTMLElement

// select all .handle children with selector string
handle: '.handle'

// set as element
handle: element.querySelector('.handle')

// set as array or NodeList
handle: [ element.querySelector('.handle1'), element.querySelector('.handle2') ]

Specifies on what element the drag interaction starts.

handle is useful for when you do not want all inner elements to be used for dragging, like inputs and forms. See back handle example on CodePen.

Events

Bind events with jQuery with standard jQuery event methods .on(), .off(), and .one(). Inside jQuery event listeners this refers to the Draggabilly element.

// jQuery
function listener(/* parameters */) {
  // get Draggabilly instance
  var draggie = $(this).data('draggabilly');
  console.log( 'eventName happened', draggie.position.x, draggie.position.y );
}
// bind event listener
$draggable.on( 'eventName', listener );
// unbind event listener
$draggable.off( 'eventName', listener );
// bind event listener to trigger once. note ONE not ON
$draggable.one( 'eventName', function() {
  console.log('eventName happened just once');
});

Bind events with vanilla JS with .on(), .off(), and .once() methods. Inside vanilla JS event listeners this refers to the Draggabilly instance.

// vanilla JS
function listener(/* parameters */) {
  console.log( 'eventName happened', this.position.x, this.position.y );
}
// bind event listener
draggie.on( 'eventName', listener );
// unbind event listener
draggie.off( 'eventName', listener );
// bind event listener to trigger once. note ONCE not ONE or ON
draggie.once( 'eventName', function() {
  console.log('eventName happened just once');
});

dragStart

Triggered when dragging starts and the element starts moving. Dragging starts after the user's pointer has moved a couple pixels to allow for clicks.

// jQuery
$draggable.on( 'dragStart', function( event, pointer ) {...})
// vanilla JS
draggie.on( 'dragStart', function( event, pointer ) {...})
  • event - Type: Event - the original mousedown or touchstart event
  • pointer - Type: MouseEvent or Touch - the event object that has .pageX and .pageY

dragMove

Triggered when dragging moves.

// jQuery
$draggable.on( 'dragMove', function( event, pointer, moveVector ) {...})
// vanilla JS
draggie.on( 'dragMove', function( event, pointer, moveVector ) {...})
  • event - Type: Event - the original mousemove or touchmove event
  • pointer - Type: MouseEvent or Touch - the event object that has .pageX and .pageY
  • moveVector Type: Object - How far the pointer has moved from its start position { x: 20, y: -30 }

dragEnd

Triggered when dragging ends.

// jQuery
$draggable.on( 'dragEnd', function( event, pointer ) {...})
// vanilla JS
draggie.on( 'dragEnd', function( event, pointer ) {...})
  • event - Type: Event - the original mouseup or touchend event
  • pointer - Type: MouseEvent or Touch - the event object that has .pageX and .pageY

pointerDown

Triggered when the user's pointer (mouse, touch, pointer) presses down.

// jQuery
$draggable.on( 'pointerDown', function( event, pointer ) {...})
// vanilla JS
draggie.on( 'pointerDown', function( event, pointer ) {...})
  • event - Type: Event - the original mousedown or touchstart event
  • pointer - Type: MouseEvent or Touch - the event object that has .pageX and .pageY

pointerMove

Triggered when the user's pointer moves.

// jQuery
$draggable.on( 'pointerMove', function( event, pointer, moveVector ) {...})
// vanilla JS
draggie.on( 'pointerMove', function( event, pointer, moveVector ) {...})
  • event - Type: Event - the original mousemove or touchmove event
  • pointer - Type: MouseEvent or Touch - the event object that has .pageX and .pageY
  • moveVector Type: Object - How far the pointer has moved from its start position { x: 20, y: -30 }

pointerUp

Triggered when the user's pointer unpresses.

// jQuery
$draggable.on( 'pointerUp', function( event, pointer ) {...})
// vanilla JS
draggie.on( 'pointerUp', function( event, pointer ) {...})
  • event - Type: Event - the original mouseup or touchend event
  • pointer - Type: MouseEvent or Touch - the event object that has .pageX and .pageY

staticClick

Triggered when the user's pointer is pressed and unpressed and has not moved enough to start dragging.

click events are hard to detect with draggable UI, as they are triggered whenever a user drags. Draggabilly's staticClick event resolves this, as it is triggered when the user has not dragged.

// jQuery
$draggable.on( 'staticClick', function( event, pointer ) {...})
// vanilla JS
draggie.on( 'staticClick', function( event, pointer ) {...})
  • event - Type: Event - the original mouseup or touchend event
  • pointer - Type: MouseEvent or Touch - the event object that has .pageX and .pageY

Methods

disable

// jQuery
$draggable.draggabilly('disable')
// vanilla JS
draggie.disable()

enable

// jQuery
$draggable.draggabilly('enable')
// vanilla JS
draggie.enable()

setPosition

// jQuery
$draggable.draggabilly( 'setPosition', x, y )
// vanilla JS
draggie.setPosition( x, y )
  • x - Type: Number - horizontal position
  • y - Type: Number - vertical position

dragEnd

Stop dragging.

// jQuery
$draggable.draggabilly('dragEnd')
// vanilla JS
draggie.dragEnd()

destroy

// jQuery
$draggable.draggabilly('destroy')
// vanilla JS
draggie.destroy()

jQuery.fn.data('draggabilly')

Get the Draggabilly instance from a jQuery object. Draggabilly instances are useful to access Draggabilly properties.

var draggie = $('.draggable').data('draggabilly')
// access Draggabilly properties
console.log( 'draggie at ' + draggie.position.x + ', ' + draggie.position.y )

Properties

position

draggie.position
// => { x: 20, y: -30 }
  • position - Type: Object
  • x - Type: Number
  • y - Type: Number

Webpack & Browserify

Install Draggabilly with npm.

npm install draggabilly
var Draggabilly = require('draggabilly');

var draggie = new Draggabilly( '.draggable', {
  // options
});

To use Draggabilly as a jQuery plugin, you need to install and call jQuery Bridget.

npm install jquery-bridget
var $ = require('jquery');
var jQueryBridget = require('jquery-bridget');
var Draggabilly = require('draggabilly');

// make Draggabilly a jQuery plugin
jQueryBridget( 'draggabilly', Draggabilly, $ );
// now you can use $().draggabilly()
$('.draggable').draggabilly({...})

Browser support

Draggabilly v3 supports Chrome 49+, Firefox 41+, Safari 14+ (mobile & desktop), and Edge 12+.

License

Draggabilly is released under the MIT License. Have at it.


Made by David DeSandro 😻

Comments
  • emit dragStart when element starts moving, not on pointer down event

    emit dragStart when element starts moving, not on pointer down event

    This is consistent with jQuery UI Draggable. It makes sense, as it prevents moving logic from being triggered when it doesn't have to.

    I'm running into a problem on a Packery+draggable demo, trying use just pointer events. When item is 'clicked' (pointer doesn't move), I want to do different logic.

    Eh, this may be problematic in the long run.

    opened by desandro 24
  • npm repo

    npm repo

    Just wanted to give you a heads up that I'm using npm as a packager for both frontend and backend code, and wanted to use Draggabilly via npm but I noticed it doesn't exist yet (https://www.npmjs.org/package/draggabilly).

    opened by davidcalhoun 16
  • Added the ability to pass an element as the handle

    Added the ability to pass an element as the handle

    Added the ability to pass an element as the handle. This enables Polymer ShadowDom elements to be used as the handle as well. Or just passing an element directly if you don't want it to use querySelectorAll();

    opened by beauwest 15
  • Not sure how to include with AMD

    Not sure how to include with AMD

    Hi!

    I'm working on a transport issue.

    When I include draggabilly.js as an AMD dependency, it tries to track down the dependencies of your library in the context of my app. Is this appropriate? Here's the output I see:

    GET http://assessments-front.dev/get-style-property.js 404 (Not Found) require.js:1872
    Uncaught Error: Script error for: get-style-property
    http://requirejs.org/docs/errors.html#scripterror require.js:163
    GET http://assessments-front.dev/classie.js 404 (Not Found) require.js:1872
    GET http://assessments-front.dev/eventEmitter.js 404 (Not Found) require.js:1872
    GET http://assessments-front.dev/eventie.js 404 (Not Found) require.js:1872
    GET http://assessments-front.dev/get-size.js 404 (Not Found)
    

    I see why this is (the amd define at the bottom of draggabilly indicates those dependencies. What is the right way to resolve this? Should I add require config to map these module names to the correct dependency path? I don't see those dependencies in the draggabilly project.

    opened by SimplGy 11
  • Distinguish on click event whether element was dragged or not

    Distinguish on click event whether element was dragged or not

    Food for thought. Let's say I have an element. A user may drag it about and drop somewhere else. They may also just quickly click on like they would a link. This element is being managed by Packery.

    The question is, what's the best way to do different things for these behaviors? By default, the click handler will be fired whenever the element is dragged. But in the click handler you have no way to tell if the element was actually moved, or whether it was a quick-click.

    A solution for this is to add a class to the element on 'dragMove', and remove that class only once you've done something after 'dragEnd'. Like packery's 'dragItemPositioned' event. The click handler fires between these two moments, so your click handler can check for that class and return early if it was recently dragged, so as not to fire 'quick click' behavior after a drag.

    Is this the best way to accomplish this?

    Example.

    Add a 'was-dragged' class between dragEnd and dragItemPositioned: https://github.com/gobengo/streamhub-packery/blob/master/src/main.js#L46

    Return early in click handler if it was recently dragged: https://github.com/gobengo/streamhub-packery/blob/master/examples/mediawall/index.html#L77

    opened by gobengo 11
  • How to manually stop dragging?

    How to manually stop dragging?

    How to leave the event if a given condition is reached?

    example:

    $('#element').draggabilly({
       containment: true,
       axis: 'x'
    }).on('dragMove', function() {
       let containerWidth = $(this).parent().width()
       let buttonWidth = $(this).outerWidth()
       let max = (containerWidth - buttonWidth) - 1 // count border right (1px)
       // condiction
       if ( $(this).position().left >= max ) {
           console.log('limit reached')
           return false // escape here!!! don't escaped!
       }
    }).on('dragEnd', function() {
       let containerWidth = $(this).parent().width()
       let buttonWidth = $(this).outerWidth()
       let max = (containerWidth - buttonWidth) - 1 // count border right (1px)
       // confirm condiction
       if ( $(this).position().left >= max ) {
           // do stuff...
       } else {
           // do stuff...
       }
    }).on('click', function() {
       //...
    })
    

    I'm assuming that return on "move" would trigger "end"? Is there a correct method?

    feature request How do I? 
    opened by subversivo58 9
  • Constrain axis movement to x or y depending on direction

    Constrain axis movement to x or y depending on direction

    Kind of having a success though.. lol. Maybe add setInterval to let user slip up the direction some.... ; )

    dragger.on('dragMove', function (instance) {
    
        if (checkAxis){
            dragX = Math.abs(instance.dragPoint.x);
            dragY = Math.abs(instance.dragPoint.y);
    
            if (dragX > dragY) {
                console.log('X ' + dragX)
                dragger.options.axis = 'x';
            } else {
                console.log('Y ' + dragY)
                dragger.options.axis = 'y';
            }
            checkAxis = false;
        }
    
    });
    
    dragger.on('dragEnd', function (instance) {
    
        checkAxis = true;
        dragger.options.axis = 'x, y';
    
    });
    
    opened by ghost 9
  • Applies Position relative on init if the element is fixed positioned

    Applies Position relative on init if the element is fixed positioned

    In _create we have..

      // set relative positioning
      var style = getStyle( this.element );
      if ( style.position !== 'relative' && style.position !== 'absolute' ) {
        this.element.style.position = 'relative';
      }
    
    opened by ahmed1490 9
  • Browser & device support

    Browser & device support

    I'm limited to testing with what I've got lying around. I would very much appreciate if you can test out http://draggabilly.desandro.com/ and report back. That'd be delightful.

    Unless noted with a :broken_heart:, Draggabilly works on the following devices and browsers. See #8 for broken devices and browsers.

    ... and lots more. Feel free to chime if you have tested it in something else.

    opened by desandro 9
  • Draggabilly delay on actual movement

    Draggabilly delay on actual movement

    Hello, I am having an issue with Packery and Draggabilly. When I drag an element there is a delay for when the element starts to move. This makes it incredibly difficult to control and the complete opposite of user-friendly. This is an example of what I'm talking about: http://littlefishfx.com/packery-test/

    As you can see (if you test it) the delay is very obvious, and it makes it difficult to control the movement of the element.

    I have a copy of the page locally, that works great. However, it's just when it's on the wordpress page.

    Maybe it could be the theme, or a plugin? Or possibly, it could be jQuery/jQuery-ui itself (even though I'm using the latest wordpress version).

    Does anyone know what could be causing this? the local version works great, and it's just the page, nothing else.

    Thanks, Kieron

    opened by kieronsutton00 8
  • added positionByTransform option

    added positionByTransform option

    I'm not sure if that will make sense to you, but I'm using your (great!) lib along with some additional logic to make smooth repositioning of cards the same way Google Keep does. It is working great. But to achieve this, all my elements inside the container have left and top zero, and are positioned by the transform property. So I had to add an option to your lib to position the elements on drag end by the transform property instead of top/left properties. This patch doesn't change the default behavior.

    opened by reinert 7
  • Fix #220 - Ignored attempt to cancel a touchstart event with cancelable=false, for example because scrolling is in progress and cannot be interrupted.

    Fix #220 - Ignored attempt to cancel a touchstart event with cancelable=false, for example because scrolling is in progress and cannot be interrupted.

    Hi,

    This PR is intended to fix the issue https://github.com/desandro/draggabilly/issues/220. You can have a look at the documentation of the Event.cancelable property:

    The cancelable read-only property of the Event interface indicates whether the event can be canceled, and therefore prevented as if the event never happened.

    If the event is not cancelable, then its cancelable property will be false and the event listener cannot stop the event from occurring.

    Most browser-native events that can be canceled are the ones that result from the user interacting with the page. Canceling the click, wheel, or beforeunload events would prevent the user from clicking on something, scrolling the page with the mouse wheel, or navigating away from the page, respectively.

    Synthetic events created by other JavaScript code define if they can be canceled when they are created.

    To cancel an event, call the preventDefault() method on the event. This keeps the implementation from executing the default action that is associated with the event.

    Event listeners that handle multiple kinds of events may want to check cancelable before invoking their preventDefault() methods.

    This part is important in our case:

    Event listeners that handle multiple kinds of events may want to check cancelable before invoking their preventDefault() methods.

    Furthermore, I have improved the dist script to support the Windows OS, since some developers are not necessarily on Linux: ec8a2fa.

    Regards.

    opened by Bugophobia 0
  • (Emitted error) Ignored attempt to cancel a touchstart event with cancelable=false, for example because scrolling is in progress and cannot be interrupted.

    (Emitted error) Ignored attempt to cancel a touchstart event with cancelable=false, for example because scrolling is in progress and cannot be interrupted.

    Hi,

    When using draggabilly with a mobile device (e.g. with the Chrome DevTools), an error is sometimes emitted in the console, but I have some trouble reproducing it without my app, so i can't show you the steps:

    [Intervention] Ignored attempt to cancel a touchstart event with cancelable=false, for example because scrolling is in progress and cannot be interrupted.
    proto.handlePointerDown @ draggabilly.js:189
    proto.emitEvent @ ev-emitter.js:86
    proto.emitEvent @ draggabilly.js:120
    proto.pointerDown @ unidragger.js:153
    proto.ontouchstart @ unidragger.js:120
    proto.handleEvent @ unidragger.js:36
    

    3

    2

    A quick fix could be something like this:

    https://github.com/desandro/draggabilly/blob/125258c6f59f0069cd2a50f29e7358de390ccbb8/draggabilly.js#L189-L189

    - event.preventDefault();
    + if ( event.cancelable ) event.preventDefault();
    

    Regards

    opened by Bugophobia 1
  • Feature: return custom containment

    Feature: return custom containment

    **feature request

    Is there a way to return a rect object if not a function instead of an element in order to set the movement contraint?

    e.g

    new Draggabilly(elem, { 
      containment: { x: 20, y: 200, width: 400, height: 400 }
    ....
    
    feature request 
    opened by karneaud 4
  • Fix for issue #92 - The element's original transform is discarded

    Fix for issue #92 - The element's original transform is discarded

    Basically an updated version of pull request #93, but with a fix for rotated elements (see peterbe's comment in issue #92 here: https://github.com/desandro/draggabilly/issues/92#issuecomment-157452101), and elements with more than one transform property.

    Implemented here: http://codepen.io/Sphinxxxx/pen/QyRRom

    opened by Sphinxxxx 3
  • Added Typescript declaration file for the Draggabilly library.

    Added Typescript declaration file for the Draggabilly library.

    Great library and I just needed dragging in a webproject without the need of the large jQueryUI library. Since I develop with Angular/Typescript it came in handy to create a declaration file. Feel free to merge it!

    opened by giespaepen 13
Releases(v3.0.0)
Owner
David DeSandro
Designer, developer @metafizzy
David DeSandro
Interactive To Do List, draggable tasks, optimized for desktop and mobile screen sizes. It reserves data in local storage. Built with HTML, CSS, and JavaScript.

To Do List Interactive daily To-Do List Built With Major languages: html, css, javascript Frameworks: Technologies used: Webpack Live Demo Live Demo L

Jafar Yousef 6 Aug 4, 2022
A library for boolean aliases to help you make your code more confusing and make your coworkers hate you.

yup-nope A library for boolean aliases to help you make your code more confusing and make your coworkers hate you. Installation Using npm: npm install

Bence A. TΓ³th 4 Dec 10, 2022
why make apps to increase focus -- when you can make apps to reduce focus

impossifocus ?? What is this? ImpossiFocus will measure focus by reading your brainwaves -- and if you're in the zone, it'll ensure that changes with

Aleem Rehmtulla 10 Nov 30, 2022
Notes may contain grammatical errors and some wont make sense and will only make sense to me

This is my own notes containing all the information and knowledge I've gained during my studying sessions. The notes are all topics that relates to technology such as computers, software or programming.

null 126 Dec 15, 2022
Make drag-and-drop easier using DropPoint. Drag content without having to open side-by-side windows

Make drag-and-drop easier using DropPoint! DropPoint helps you drag content without having to open side-by-side windows Works on Windows, Linux and Ma

Sudev Suresh Sreedevi 391 Dec 29, 2022
Trying to make a game engine apparently.

Clockwork - a game engine from scratch The goal of this project is to build a game engine, I still don't know what it needs to do, but will update thi

Anas Mazouni 2 Oct 31, 2021
Make sure a specific version and package-manger to be used in project.

pm-keeper A simple way to force package-manager in your project. usage Add a preinstall script in your project's package.json, link this: { "scripts

ι˜ΏδΊ” 13 Sep 25, 2022
Make clone chrome. With the help of a nomad coder

clone_momentum Make clone momentum. With the help of a nomad coder https://taeminchoe.github.io/clone_momentum/ Description of each function 1. Login

μ΅œνƒœλ―Ό(Taemin Choe) 1 Dec 26, 2021
Javascript engine to make fast games.

G3 Javascript Basic javascript engine to make fast games and write clean code. ??️ Example code: const g3 = new G3() const Window = g3.createWindow("

Starship Code 2 Feb 13, 2022
Make the content slide prettily across the screen with variable sizes of scrolling items, in any of four directions, pausing while the mouse is over the marquee, and all with vanilla JavaScript.

TEG Marquee Make the content slide prettily across the screen with variable sizes of scrolling items, in any of four directions, pausing while the mou

Paul B. Joiner 0 Dec 30, 2021
"Math magicians" is a website for all fans of mathematics. It is a Single Page App (SPA) that allows users to: Make simple calculations. Read a random math-related quote.

math-magicians A Single Page App (SPA) that allows users to Make simple calculations and read a random math-related quote. "Math magicians" is a websi

Temitope Ogunleye 3 Feb 21, 2022
Make use of your favicon with badges, images or videos

favico.js More info here. Author Miroslav Magda Version 0.3.9 Contributors: Serge Barysiuk, pissflaps, Yaroslav Yakovlev, LoicMahieu, Renan Gonçalves,

Miroslav Magda 8.7k Dec 21, 2022
Use pulsar to make custom trading strategy that uses Flashloans at low cost. No contract deployment required.

PULSAR Pulsar is a contract that will let you execute custom call on the blockchain and let you make use of the Flasloans in your trading sequences. Y

idecentralize.finance 9 Jun 6, 2022
✨This is My Personal Website's Source Code. πŸ‘¨β€πŸ’» I Make it with Next.js and WindiCSS

?? drackin.tk This is my personal website with Next.js + WindiCSS ☁ Weather API You can use my Weather API to see weather of locations. Simple Request

Drackin Best 5 Dec 15, 2022
This is an imitation of the Amazon online shopping store. Users can add and remove items from the cart, proceed to checkout and make payments.

AMAZON This is an imitation of the Amazon online shopping store. Users can add and remove items from the cart, proceed to checkout and make payments.

Kevv_in 7 Mar 23, 2022
JavaScript library to make drawing animation on SVG

vivus.js Demo available on http://maxwellito.github.io/vivus Play with it on Vivus Instant Vivus is a lightweight JavaScript class (with no dependenci

maxwellito 14.5k Jan 3, 2023