This plugin leverages the special event api, to add bind-able drop behavior events. This plugin is designed to work exclusively with $.event.special.drag, actually, it doesn't work without it.
Download - jQuery 1.2.6+ required, jquery.event.drag 1.0+ required.
This plugin compares "dragProxy" position and registered drop target positions asynchronously, based on some tolerance mode. Some plugins check positions over often on every mousemove event, which can hinder performance. This plugin uses a fixed delay and only compares positions while the mouse is moving.
The available events using this plugin are...
- dropstart - When a drop target becomes active, depends on tolerance mode and dragProxy. Return false to prevent drop.
- drop - When a dragged element is released within an active drop target. Return false to null the "dropTarget" event property prior to calling "dragend".
- dropend - When a drop target becomes inactive.
The "dropTarget" event property is updated (in addition to drag event properties) to reflect the single active drop target element. When completing your drag/drop interaction, in the "dragend" handler the "dropTarget" property can be used to detrmine whether a drop happend or not.
The drop target position and size is captured and cached at the time of the drag event binding. If your application is highly dynamic, you can use the $.dropManage utility to filter and re-cache drop target element locations.
// bind a drop event handler
$( elems ).bind( "drop", function(){ ... });
There are several stored tolerance modes already...
- mouse - This mode is not explicitly defined, but is the fallback mode if no other mode is properly specified.
- overlap - The target element which shares the most overlapping area with the proxy element wins.
- intersect (Default) - The target element which contains the mouse (cursor) wins, else target element with most overlapping area wins.
- fit - The proxy element is completely contained within target element bounds.
- middle - The center point of the proxy element is contained within target element bounds.
Demo - Use the select to try different tolerance mode settings.
$.dropManage( options )
"dropManage" is a global utility function, that takes a single options argument in the form of an object literal. The options will extend the $.event.special.drop object, which allows you to use the following keys for configuration. The function returns a jquery collection of filtered drop target elements.
- delay - The async timeout delay (default: 100) in milliseconds between target tolerance checks.
- mode - Key string (default:'intersect') for stored tolerance modes.
- tolerance - Create a function to make a custom tolerance mode.
- filter - jQuery filter method argument (string expression or function) to filter the all currently bound drop target elements and cache the position and size.
The most typical place to use the $.dropManage function, is inside of a "dragstart" event. In dynamic applications, where the drop target elements will change size or position, you can re-locate elements quite easily. It also makes it easy to interact with a restricted subset of all bound drop target elements and different tolerance modes.
// filter drop elements, set new tolerance mode
$.dropManage({ mode:'fit', filter:'.red' });
Demo - Drag the drop target to a different location, this demo uses "$.dropManage" to relocate elements on each "dragstart" event.
You can create and store your own custom tolerance modes be extending the "$.event.special.drop.modes" object with a new function. The function scope, when called, is the "$.event.special.drop" (this keyword). The function receives three arguments:
- event - the most recent mousemove/drag event.
- proxy - a location object representing the drag proxy element.
- target - a location object representing the drop target element.
A location object is a handy object literal that is returned from the "$.event.special.drop.locate" helper function. The location object values are:
- elem - the DOM element that is represented.
- L - the LEFT position of the element.
- W - the WIDTH of the element
- R - the RIGHT position of the element (Left + Width).
- T - the TOP position of the element.
- B - the BOTTOM position of the element (Top + Height).
- H - the HEIGHT of the element.
Another helper function is "$.event.special.drop.contains" which takes two arguments: the target location, and the test location. The first argument should always be the drop element "location" object, the second argument could be the drag proxy location or a 2 value array representing XY coordinates respectively. The "contains" function returns true or false.
Using the helper functions to determine you custom tolerance mode, your tolerance function can return the target location object of the outright winning element, or null to continue comparing. In addition, you can set the "best" parameter of the "$.event.special.drop" object to continue comparing all drop targets before choosing a winner. Hopefully the examples below will help make things more clear.
// tolerance function scope is '$.event.special.drop'
// 'fit' tolerance mode uses the 'contains' function
$.event.special.drop.modes['fit'] = function( event, proxy, target ){
// returns an outright winner, or null
return this.contains( target, proxy ) ? target : null;
};
// 'intersect' mode is a complex example
$.event.special.drop.modes['intersect'] = function( event, proxy, target ){
// returns an outright winner if cursor is inside
return this.contains( target, [ event.pageX, event.pageY ] ) ?
// else reverts to 'overlap' mode
target : this.modes['overlap'].apply( this, arguments );
};
Lastly, there is an overloaded jquery method called "drop" which takes zero to three arguments.
// 0 args, trigger "drop" handler
$( elems ).drop();
// 1 arg, binds "drop" handler
$( elems ).drop( dropFn );
// 2 args, binds "dropstart" and "drop" handlers
$( elems ).drop( dropstartFn, dropFn );
// 3 args, binds "dropstart" and "drop" and "dropend" handlers
$( elems ).drop( dropstartFn, dropFn, dropendFn );
Please direct any feedback to http://groups.google.com/group/threedubmedia