Giter Club home page Giter Club logo

draggable's Introduction

draggable

High performance, fully cross browser, full featured drag and drop in a tiny (2k gzipped), dependency-free package.

Demo

http://bcherny.github.io/draggable/demos/basic/

Usage

HTML

<div id="id"></div>

JavaScript

Using browser globals:

var element = document.getElementById('id');
var options = {
  grid: 10,
  onDrag: function(){ ... }
};
new Draggable (element, options);

Using AMD/CommonJS:

var Draggable = require ('Draggable');
var element = document.getElementById('id');
new Draggable (element);

Dependencies

None!

Options

Option Type Default Description
grid Number 0 grid size for snapping on drag
handle Element null the handle of the draggable; if null, the whole element is the handle
filterTarget Function(target) null prevent drag when target passes this test
limit Element, Function(x, y, x0, y0), or Object { x: null, y: null } limit x/y drag bounds
threshold Number 0 threshold before drag begins (in px)
setCursor Boolean (truthy) false change cursor to move?
setPosition Boolean (truthy) true change draggable position to absolute?
smoothDrag Boolean (truthy) true snap to grid only when dropped, not during drag
useGPU Boolean (truthy) true move graphics calculation/composition to the GPU? (modern browsers only, graceful degradation)

Events

Event Arguments
onDrag element, x, y, event
onDragStart element, x, y, event
onDragEnd element, x, y, event

Instance methods

Method Arguments Returns Description
get --- {Object} {x, y} Get the current coordinates
set {Number} x, {Number} y instance Move to the specified coordinates
setOption {String} property, {Mixed} value instance Set an option in the live instance
destroy --- --- Unbind the instance's DOM event listeners

Notes

Options.limit accepts arguments in several forms:

// no limit
limit: null

// limit x, but leave y unbounded
limit: {
  x: [1,10],
  y: null
}

// limit both axes
limit: {
  x: [1,10],
  y: [1,500]
}

// bound x, set y to a constant
limit: {
  x: [1,10],
  y: 5
}

// bound with an element
limit: document.getElementById('id')

// bound with a custom function
limit: function (
  x,  // current X coordinate
  y,  // current Y coordinate
  x0, // original X coordinate (where drag was started)
  y0  // original Y coordinate (where drag was started)
) {

  var radius = 100,
    dx = x - x0,
    dy = y - y0,
    distance = Math.sqrt(dx*dx + dy*dy),

    // only allow dragging within a circle of radius 100
    outOfRange = distance > radius;


  // if our point is outside of the circle, compute the
  // point on the circle's edge closest to our point
  if (outOfRange) {

    x = x0 + radius * (x - x0) / distance;
    y = y0 + radius * (y - y0) / distance;

  }

  return {
    x: x,
    y: y
  };

}

Tested on

  • Chrome 29 on OSX
  • Chrome 28 on Windows
  • Firefox 23 on OSX
  • Firefox 21 on Windows
  • Opera 16 on OSX
  • Safari 6 on OSX
  • Safari 6 on iPhone4/iOS6
  • Safari 6 on iPhone5/iOS6
  • Safari 6 on iPad2/iOS6
  • Safari 6 on iPad3/iOS6
  • Internet Explorer 8-10 on Windows

To do

  • Improve performance on old iOS
  • Unit tests

draggable's People

Contributors

bcherny avatar igorjacauna avatar mderijcke avatar mitch-rickman avatar potomak avatar swang avatar thedanheller avatar thomashickman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

draggable's Issues

Error occured while using the lib for server side rendering

I`m using React server side rendering features and ES6.
Using ES6 importing style like

import draggable from 'draggable';

has issue with document object:

/node_modules/draggable/src/draggable.js:43
var style = document.body.style;
^

ReferenceError: document is not defined.

browserify could not find module 'jQuery'

browserify src/draggable.js --s Draggable | uglifyjs -c > draggable.js
Error: Cannot find module 'jQuery' from '/home/engine/node_modules/draggable/src'
at /usr/lib/node_modules/browserify/node_modules/resolve/lib/async.js:46:17
at process (/usr/lib/node_modules/browserify/node_modules/resolve/lib/async.js:173:43)
at ondir (/usr/lib/node_modules/browserify/node_modules/resolve/lib/async.js:188:17)
at load (/usr/lib/node_modules/browserify/node_modules/resolve/lib/async.js:69:43)
at onex (/usr/lib/node_modules/browserify/node_modules/resolve/lib/async.js:92:31)
at /usr/lib/node_modules/browserify/node_modules/resolve/lib/async.js:22:47
at Object.oncomplete (fs.js:108:15)

Textarea

Is that possible to drag text area w/o blocking it from input?)

Handle element

I have implemented a handle element feature. It can be found here.

If you think you'll use it I can create a PR after the other one was closed.

(Thanks for this lib, btw, really good one).

Content clicks don't register on mobile devices

Hi!

Great working library, works really well. However, I noticed one thing on mobile browsers:

  • if there are buttons inside the dragged content, and you've not specified a drag handle (i.e. making the element itself the handle), those buttons don't work at all - tapping them does nothing

Seen on Samsung Tab S6 Lite and Apple iPad Mini 5 (2019):

  • Android 11 Samsung Internet Browser
  • Android 11 Chrome
  • Android 11 Firefox
  • iPadOS 14.6 Safari
  • iPadOS 14-6 Firefox

In summary, looks like touch events are handled a little differently from mouse events.

The obvious workaround is to use a drag handle whenever there is clickable content inside - I was just wondering if there is something else that can be done.

Draggable iframe

I've been trying to get an iframe element itself (not any elements inside the iframe) to be draggable - is this possible? Thank you!

How to use as drag and drop

Hi
how can i use this as a drag and drop alternative
Any example on how to move elements by dragging from one node to another
thanks

how to using filterTarget prop

my html:

<div id="drag1" style="background-color:#0094ff;width:100px;height:100px;display:flex;align-items:center;justify-content:center;">
<a href="javascript:;">click drag</a>
</div>

my js code:

var options = {
            grid: 10,
            onDrag: function () { },
            handle:'div',
            filterTarget: function () { }
        };
new Draggable ($('#drag1')[0], options);

I want to drag by the div area not the anchor('a') area,so i using filterTarget prop,but it doesn't work.
It's why?

How to set default position for element?

The top and left is 0px by default. Is there any way to custom those values?

    transform: translate3d(0px, 0px, 0px);
    display: block;
    left: 0px;
    top: 0px;
    width: 385px;
    height: 54px;
    right: auto;
    bottom: auto;
    margin: 0px;
    position: absolute;

Draggabble mouse handlers doesn't work on devices with touchscreen

Hello, there is an issue preventing me from using this package:
My notebook has a touch screen, but I use mouse to interact with web pages.
In my case the script doesn't work at all due to handlers attached only to touch events.
In general, you cannot assume anything about user input devices based on touch functions availability.

BTW, thanks for cutting out jQuery, that's awesome!

Error with webpack when importing ES6 style

I'm importing it via ES6 import and getting this error message:

p5.controller.js:684 Uncaught TypeError: Cannot read property 'style' of null(โ€ฆ).

It doesn't happen when I check if document.body exists in the transform function.

require syntax

In the readme :

var Draggable = require ('Draggable');

should be :

var Draggable = require ('draggable');

(in lowercase)
It will not build except on windows with the uppercase D

Make Draggable an emitter

So we can do stuff like:

new Draggable(...)
  .on('dragStart', ...)
  .on('dragEnd', ...)
  .trigger('dragStart')
  .off('dragStart')

See #6

Allow instances to handle more than one element

Hi. Just seeing if you're interesting in adding this before I implement it.

I want to have one instance of Draggable handle all elements that match an element. Easiest example is I have a chessboard and want to be able to drag all the pieces on the board without having to declare 32 instances of Draggable. E.g. I want to specify that I want all (<div class="piece"></div>) that are children of a parent element (<div class="board"></div>) be draggable.

The way I'm thinking of implementing this is to specify a new parentEle parameter, and make element accept a string. Then only need an event listener attached to parentEle instead of for each element. I'm not dead-set on names/functionality so if you are interested, would love to hear your feedback about how the API should work for this.

I know this library wants to support IE8, and it seems that querySelectorAll actually works in IE8, but only if its in standards mode[0]. I don't think polyfilling querySelectorAll would be worth it just to support IE8 quirks/compat modes. So implementing this for IE8 standards-only mode is what I would target. Then I guess if users need to support IE8 in non-standards mode they could just polyfill querySelectorAll.

Obviously the original methods would stay the same way in terms of supporting IE8, the requirement would only be for this new functionality.

If you don't think this library's core should support multiple elements, or if features need to support all modes of IE8 then I'll just fork the library. But I thought I'd see if there was interest in adding this to the main library (with the IE8 caveats) before rewriting it for myself.

[0] http://web.archive.org/web/20171004213917/https://msdn.microsoft.com/en-us/library/ff462057.aspx#selectorapi (The Selectors API is defined as part of the Selectors API specification and is only available to Web pages displayed in IE8 standards mode)

destroy ?

hey ,how i can destroy all events ref to this.
ex:
new Draggable (div,DraggableOptions);

than if i remove the div, how i can do Draggable.destroy(); ?

Trigger an event ?

Hello !

I'm currently using this lib and I want to know if it's possible to "trigger" a drag event manually like myElement.trigger('drag');
Obviously this doesn't work but maybe there is another way ?

Thanks you !

Limit by element doesn't work (Vue.js)

Using this with Vue. Any idea why?

Vue.directive('draggable', {
    bind: function(element) {
        const options = {
            limit: document.getElementById('unlock-slider'),
        };
        const draggable = new Draggable(element, options);
    }
})

And then in my template literal:

<div id="unlock-slider" class="unlock-slider">
    <div class="unlock-link">
        <img :src="signUpSlideButton"> &nbsp;&nbsp;
        <router-link to="/login">
            <b>login</b>
        </router-link>
        &nbsp;&nbsp;
        <img :src="signUpSlideButton">
    </div>
    <img class="unlock-key" :src="signingKeyNormal" v-draggable>
    <img class="unlock-lock" :src="signinLock">
</div>

I've seen the bound demo and it works nicely, so I'm assuming it's something within Vue, but I'm still pretty new to it.

Case sensitivity in packages names

Hi, in the 'dependencies' section of package.json you specified 'jquery' package as a dependency, but within draggable.js you require it as 'jQuery'.

On case-sensitive file systems (all linux) this will break, as require() is case-sensitive.
The possible solution is to require jquery with lowercase for all OS/filesystems compatibility.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.