YUI recommends YUI3.

YUI 2 has been deprecated since 2011. This site acts as an archive for files and documentation.

This documentation is no longer maintained.

YUI 2: Drag & Drop

YUI 2: Drag & Drop

The Drag & Drop Utility allows you to create a draggable interface efficiently, buffering you from browser-level abnormalities and enabling you to focus on the interesting logic surrounding your particular implementation. This component enables you to create a variety of standard draggable objects with just a few lines of code and then, using its extensive API, add your own specific implementation logic.

For more information about drag and drop as a design pattern, see the Yahoo! Design Pattern Libary.

Getting Started

To use Drag and Drop, include the following source files in your web page with the script tag:

  1. <!-- Dependencies -->
  2. <script src="http://yui.yahooapis.com/2.9.0/build/yahoo-dom-event/yahoo-dom-event.js" ></script>
  3.  
  4. <!-- Drag and Drop source file -->
  5. <script src="http://yui.yahooapis.com/2.9.0/build/dragdrop/dragdrop-min.js" ></script>
  6.  
<!-- Dependencies -->
<script src="http://yui.yahooapis.com/2.9.0/build/yahoo-dom-event/yahoo-dom-event.js" ></script>
 
<!-- Drag and Drop source file -->
<script src="http://yui.yahooapis.com/2.9.0/build/dragdrop/dragdrop-min.js" ></script>
 

YUI dependency configurator.

YUI Dependency Configurator:

Instead of copying and pasting the filepaths above, try letting the YUI dependency Configurator determine the optimal file list for your desired components; the Configurator uses YUI Loader to write out the full HTML for including the precise files you need for your implementation.

Note: If you wish to include this component via the YUI Loader, its module name is dragdrop. (Click here for the full list of module names for YUI Loader.)

Where these files come from: The files included using the text above will be served from Yahoo! servers. JavaScript files are minified, meaning that comments and white space have been removed to make them more efficient to download. To use the full, commented versions or the -debug versions of YUI JavaScript files, please download the library distribution and host the files on your own server.

Order matters: As is the case generally with JavaScript and CSS, order matters; these files should be included in the order specified above. If you include files in the wrong order, errors may result.

Basic Drag and Drop

To enable a simple drag and drop of any DOM element, create a new instance of YAHOO.util.DD, providing the constructor with the HTML id of the element you want to make draggable. Optionally, you can provide an element reference instead of an id

  1. var dd1 = new YAHOO.util.DD("element1");
  2. // alternatively, use an element reference
  3. // var el=YAHOO.util.Dom.get("element1");
  4. // var dd1 = new YAHOO.util.DD(el);
  5.  
var dd1 = new YAHOO.util.DD("element1");
// alternatively, use an element reference
// var el=YAHOO.util.Dom.get("element1");
// var dd1 = new YAHOO.util.DD(el);
 

In this example, a new instance of YAHOO.util.DD is created for an element whose HTML id is "element1"; this enables "element1" to be dragged and dropped. Note that while the element can now be moved visually on the page, this visual motion is accomplished by changing the element's style properties. Its actual location in the DOM itself remains unchanged.

In many Drag and Drop implementations, the dragged element does not track with the mouse while being moved — often because it is large and tends to obscure information beneath it during the drag. One solution to this problem is to use a proxy element, usually a smaller visual representation of the original, that tracks with the mouse during a drag event. The Drag and Drop Utility makes it extremely easy to accomplish this effect; simply instantiate YAHOO.util.DDProxy instead of YAHOO.util.DD:

  1. var dd2 = new YAHOO.util.DDProxy("element2");
  2.  
var dd2 = new YAHOO.util.DDProxy("element2");
 

In this case, "element2" is made draggable, but during the drag event it will be represented visually by a proxy element created automatically by the Drag and Drop Utility. See the API documentation for YAHOO.util.DDProxy for more information about how to access and stylize this proxy element. When the drag interaction is completed, "element2" will move to the drop position and the proxy element will be hidden.

In addition to YAHOO.util.DD and YAHOO.util.DDProxy, a third type of Drag and Drop object is available with the utility: the target object (YAHOO.util.DDTarget). Targets are elements that participate in the drag interaction (that is, you are made aware that they are being dragged over or dropped upon) but that are not themselves draggable.

  1. var dd3 = new YAHOO.util.DDTarget("element3");
  2.  
var dd3 = new YAHOO.util.DDTarget("element3");
 

In the example above, the HTML element whose ID is "element3" serves as a target for Drag and Drop interactions, but the user cannot drag "element3" itself.

See the examples below in Using Drag and Drop or the API Documentation for more details.

Using Drag and Drop

This section describes several common features and uses and of Drag and Drop. See the Examples for additional code and implementation samples.

The Drag and Drop Manager

Drag and Drop operations within a page are managed by the Drag and Drop Manager, a singleton object accessible as YAHOO.util.DragDropMgr (this object can also be referenced via its shorter alias, YAHOO.util.DDM). The Drag and Drop Manager controls a variety of key settings that may be of interest to you in configuring Drag and Drop interactions — for example, the time delay that defines when a mousedown event becomes a drag event is configured via YAHOO.util.DragDropMgr:

  1. //sets the time delay between a mousedown and a
  2. //drag event to 1200 milliseconds:
  3. YAHOO.util.DragDropMgr.clickTimeThresh = 1200;
  4.  
//sets the time delay between a mousedown and a
//drag event to 1200 milliseconds:
YAHOO.util.DragDropMgr.clickTimeThresh = 1200;
 

A variety of other useful settings are configured via YAHOO.util.DragDropMgr; see the API documentation for this object to read more about its capabilities.

Using Interaction Groups

Each Drag and Drop object belongs to one or more interaction groups. Drag and Drop events fire only when the dragged element interacts with other objects that with which it shares a group membership. If no group is specified in the constructor, an object belongs to the "default" group.

  1. // No group specified so dd0 is assigned to the "default" group
  2. var dd0 = new YAHOO.util.DD("elementid0");
  3. // dd1 is a member of group1
  4. var dd1 = new YAHOO.util.DD("elementid1", "group1");
  5. // dd2 is a member of group2
  6. var dd2 = new YAHOO.util.DD("elementid2", "group2");
  7. // dd3 is a member of both group1 and group2
  8. var dd3 = new YAHOO.util.DD("elementid3", "group1");
  9. dd3.addToGroup("group2");
  10. //groups can be removed via script as well:
  11. dd1.removeFromGroup("group1");
  12.  
// No group specified so dd0 is assigned to the "default" group
var dd0 = new YAHOO.util.DD("elementid0");
// dd1 is a member of group1
var dd1 = new YAHOO.util.DD("elementid1", "group1");
// dd2 is a member of group2
var dd2 = new YAHOO.util.DD("elementid2", "group2");
// dd3 is a member of both group1 and group2
var dd3 = new YAHOO.util.DD("elementid3", "group1");
dd3.addToGroup("group2");
//groups can be removed via script as well:
dd1.removeFromGroup("group1");
 

Optional Configuration Parameters

An optional third argument in drag-and-drop object constructors is an object literal containing configuration info for well-known properties. The following example uses this configuration object to specify an existing HTML element as the drag proxy for this instance instead of the default:

  1. var dd = new YAHOO.example.DDProxy("dragDiv1", "proxytest", {
  2. dragElId: "existingProxyDiv"
  3. });
  4.  
var dd = new YAHOO.example.DDProxy("dragDiv1", "proxytest", {
        dragElId: "existingProxyDiv"
});
 

The following configuration properties are currently supported via the contructor's configuration object:

  • YAHOO.util.DragDrop: padding, isTarget, maintainOffset, primaryButtonOnly
  • YAHOO.util.DD (in addition to those in YAHOO.util.DragDrop): scroll
  • YAHOO.util.DDProxy (in addition to those in YAHOO.util.DD): resizeFrame, centerFrame, dragElId

All of these properties are public fields in the respective classes. See the API documentation for information about the fields.

Interesting Moments

Simply making an object draggable rarely suffices to achieve the desired interaction behavior for a drag-and-drop implementation. In most cases, Drag and Drop requires that you write code to respond to the interesting moments in the interaction: when the drag event starts, when the dragged object enters another object, and so on. The Drag and Drop Utility provides methods that fire during each of the interesting moments of the interaction. You customize your implementation by supplying the code for these methods (all of which are members of the YAHOO.util.DD, YAHOO.util.DDProxy, and YAHOO.util.DDTarget).

Moment Description
onMouseDown Provides access to the mousedown event. The mousedown does not always result in a drag operation.
startDrag Occurs after a mouse down and the drag threshold has been met. The drag threshold default is either 3 pixels of mouse movement or 1 full second of holding the mousedown.
onDrag Occurs every mousemove event while dragging.
onDragEnter Occurs when the dragged object first interacts with another targettable drag and drop object.
onDragOver Fires every mousemove event while over a drag and drop object.
onDragOut Fires when a dragged object is no longer over an object that had the onDragEnter fire.
onDragDrop Fires when the dragged objects is dropped on another.
onInvalidDrop Fires when the dragged objects is dropped in a location that contains no drop targets.
endDrag Fires on the mouseup event after a drag has been initiated (startDrag fired).
onMouseUp Fires on the mouseup event whether or not a drag was initiated.

Custom Events

In version 2.5.0, Custom Events were added to all DragDrop instances. See the API documentation for information about the events.

Event Description
mouseDownEvent Provides access to the mousedown event. The mousedown does not always result in a drag operation.
mouseUpEvent Fired from inside DragDropMgr when the drag operation is finished.
startDragEvent Occurs after a mouse down and the drag threshold has been met. The drag threshold default is either 3 pixels of mouse movement or 1 full second of holding the mousedown.
endDragEvent Fires on the mouseup event after a drag has been initiated (startDrag fired).
dragEvent Occurs every mousemove event while dragging.
invalidDropEvent Fires when the dragged objects is dropped in a location that contains no drop targets.
dragOutEvent Fires when a dragged object is no longer over an object that had the onDragEnter fire.
dragEnterEvent Occurs when the dragged object first interacts with another targettable drag and drop object.
dragOverEvent Fires every mousemove event while over a drag and drop object.
dragDropEvent Fires when the dragged objects is dropped on another.

You can subscribe to these events using the on method for the DragDrop instance.

  1. var dd = new YAHOO.util.DD('demo');
  2. dd.on('dragEvent', function(ev) {
  3. YAHOO.log('Element is being dragged.');
  4. }, dd, true);
  5.  
var dd = new YAHOO.util.DD('demo');
dd.on('dragEvent', function(ev) {
    YAHOO.log('Element is being dragged.');
}, dd, true);
 

Point Mode versus Intersect Mode

By default, the drag and drop interaction is defined by the location of the mouse cursor during the drag operation (Point mode). Intersect mode takes into account the dragged element's dimensions, reporting when that element intersects with any other drag and drop element in its group or groups.

You can switch from point mode to intersect mode at any time by setting the property YAHOO.util.DDM.mode to the constant YAHOO.util.DDM.INTERSECT.

  1. //set Drag and Drop to Intersect mode:
  2. YAHOO.util.DDM.mode = YAHOO.util.DDM.INTERSECT;
  3.  
  4. //set Drag and Drop to Point mode (default):
  5. YAHOO.util.DDM.mode = YAHOO.util.DDM.POINT;
  6.  
//set Drag and Drop to Intersect mode:
YAHOO.util.DDM.mode = YAHOO.util.DDM.INTERSECT;
 
//set Drag and Drop to Point mode (default):
YAHOO.util.DDM.mode = YAHOO.util.DDM.POINT;
 

A major side effect of switching to intersect mode is that it becomes far more likely that multiple Drag and Drop objects will be overlapping during a drag event — which means that events like onDragEnter and especially onDragOver will be firing much more often.

Because of this, the API's interesting moments are handled somewhat differently in each mode. The following table describes the core differences between API events in Point mode and Intersect mode:

Moment Point Mode Intersect Mode Notes
onMouseDown e e e is the mousedown event
startDrag x, y x, y x,y is the location of the mousedown
onDrag e e e is the mousemove event
onDragEnter e, id e, DDArray e is the mousemove event; id is the drag and drop object involved; DDarray is an array of drag and drop objects
onDragOver e, id e, DDArray e is the mousemove event; id is the drag and drop object involved; DDarray is an array of drag and drop objects
onDragOut e, id e, DDArray e is the mousemove event; id is the drag and drop object involved; DDarray is an array of drag and drop objects
onDragDrop e, id e, DDArray e is the mouseup event; id is the drag and drop object involved; DDarray is an array of drag and drop objects
onInvalidDrop e e e is the mouseup event;
endDrag e e e is the mouseup event;
onMouseUp e e e is the mouseup event;

Point mode returns the id of the target Drag and Drop object (e.g., the object over which you are dragging in onDragDrop), while Intersect mode returns an array of Drag and Drop objects instead.Note: it is possible to have stacked Drag and Drop objects — objects which overlap each other spatially. In Point mode, a drop on two stacked items would result in two onDragDrop events being fired; in Intersect mode, only one event is triggered, but an array of targeted objects is passed to that single event handler.

The reason the Drag and Drop objects are passed to the event handler in Intersect mode is that they contain properties about the interaction that can help determine the most appropriate response in your implementation:

  • The cursorIsOver property is true if the mouse cursor was over the Drag and Drop element when the interaction happened. Often this will be an important factor as you calculate the intent of the user.
  • The overlap property is a YAHOO.util.Region object that specifies the location and dimensions of the overlap of the two Drag and Drop objects. The size of this region can be used to determine which element had more overlap (YAHOO.util.Region.getArea).
  • The getBestMatch method uses the two strategies above to deduce which among the multiple matches is the most significant. The getBestMatch method returns either the first match it finds for which cursorIsOver is true, or (if the cursor is not over a target) the one with the largest overlap.

Using the Drag Shim

2.6.0 introduces the use of the Drag Shim to help with dragging over troublesome nodes. The Drag Shim is used to track the mousemove at a higher level instead of at the document level.

You can use this setting to allow dragging a node over an iframe or other such element that traps mouse events.

You can either use the Drag Shim on a per instance basis or on all draggable nodes.

  1. //Instance based at creation
  2. var dd = new YAHOO.util.DDProxy('demo', {
  3. useShim: true
  4. });
  5.  
  6. //Instance based at runtime
  7. //Must be called before startDrag to take effect.
  8. dd.useShim = true;
  9.  
  10. //All DD objects on the page
  11. YAHOO.util.DDM.useShim = true;
  12.  
//Instance based at creation
var dd = new YAHOO.util.DDProxy('demo', {
    useShim: true
});
 
//Instance based at runtime
//Must be called before startDrag to take effect.
dd.useShim = true;
 
//All DD objects on the page
YAHOO.util.DDM.useShim = true;
 

Notes on Performance

The complexity of the application logic in the interesting moments of Drag and Drop can have significant performance implications. This is particularly true of the onDrag event; onDragOver fires with every mouseMove event reported by the browser during a drag interaction. Optimize your onDrag (and, similarly, your onDragOver) code as much as possible; try to avoid iterative code, opting for object hashtables in the event that you need to perform basic data lookups each time the event fires.

Getting and setting the position of elements, an intrinsic aspect of drag interactions, gets progressively more expensive the deeper the element is in the DOM. If you encounter performance issues using Drag and Drop, consider using YAHOO.util.DDProxy instead of YAHOO.util.DD; the proxy element is absolutely positioned in the document body and therefore requires fewer cycles for repositioning.

Drag and Drop Storyboard Matrix

Storyboarding can be a powerful strategy for thinking through a rich interaction during the design phase. We have created a storyboard matrix for Drag and Drop (ZIPed XLS file) that helps you track the actors and the events that are important when a Drag and Drop interaction is taking place. Interesting moments (which correspond to API events for which you can write handlers) are listed across the top; each row in the matrix represents an element.

Drag and Drop storyboard matrix

Support & Community

The YUI Library and related topics are discussed on the on the YUILibrary.com forums.

Also be sure to check out YUIBlog for updates and articles about the YUI Library written by the library's developers.

Filing Bugs & Feature Requests

The YUI Library's public bug tracking and feature request repositories are located on the YUILibrary.com site. Before filing new feature requests or bug reports, please review our reporting guidelines.

Drag & Drop Utility Cheat Sheet:

Cheat Sheet for the Drag and Drop Utility.

Download full set of cheat sheets.

More Reading about the YUI Drag & Drop Utility:

YUI Drag & Drop on del.icio.us:

Copyright © 2013 Yahoo! Inc. All rights reserved.

Privacy Policy - Copyright Policy - Job Openings