Article Introduction: The basic concept of drag-and-drop is simple: Create an absolutely positioned element so that it can be moved with the mouse. This technique comes from a classic web page trick called "Mouse Tail". The end of the mouse is one or more pictures that move along the page with the mouse pointer. |
Drag-and-drop is a very popular user interface pattern. Its concept is simple: Click on an object, the soldier hold down the mouse button, move the mouse to another area, and then release the mouse button to speak the object "put" here. The drag-and-drop feature is also popular on the web, becoming a candidate for a more traditional configuration interface.
The basic concept of drag-and-drop is simple: Create an absolutely positioned element so that it can be moved with the mouse. This technique comes from a classic web page trick called "Mouse Tail". The end of the mouse is one or more pictures that move along the page with the mouse pointer. The basic code for a single-element mouse tail needs to set up a OnMouseMove event handler for the document, which always moves the specified element to the position of the mouse pointer, as shown in the following example:
Eventutil.addhandler (document, "MouseMove", function (event) {
var mydiv = document.getElementById ("mydiv");
MyDiv.style.left = Event.clientx + "px";
MyDiv.style.top = Event.clienty + "px";
});
In this example, the left and top coordinates of the element are set to the Clientx and Clienty properties of the event object, which puts the element in the position of the pointer to the viewport. The effect is that an element always follows the pointer's movement on the page. When the right moment (when the mouse button is pressed) implements the feature, and then deletes it (when the mouse button is released), you can drag and drop it. The simplest drag-and-drop interface can be implemented with the following code:
var DragDrop = function () {var dragging = null;
function Handleevent (event) {//get events and targets = Eventutil.getevent (event);
var target = Eventutil.gettarget (event); Determine the event type switch (event.type) {case "MouseDown": if (target.className.indexOf ("Dra
Ggable ") >-1) {dragging = target;
} break; Case "MouseMove": if (dragging!== null) {//Get event events = Eventut
Il.getevent (event);
Specify position dragging.style.left = event.clientx + "px";
Dragging.style.top = Event.clienty + "px";
} break;
Case "MouseUp": dragging = null;
Break
}
}; Public interface Return {enable:function () {EventutIl.addhandler (document, "MouseDown", handleevent);
Eventutil.addhandler (document, "MouseMove", handleevent);
Eventutil.addhandler (document, "MouseUp", handleevent);
}, Disable:function () {Eventutil.removehandler (document, "MouseDown", handleevent);
Eventutil.removehandler (document, "MouseMove", handleevent);
Eventutil.removehandler (document, "MouseUp", handleevent);
}
}
}(); Enable drag-and-drop dragdrop.enable ();
The DragDrop object encapsulates all the basic functions of drag-and-drop, which is a single instance object and uses a modular pattern to hide some implementation details. The dragging variable starts with NULL, and the dragged element is stored, so when the variable is not NULL, you know you are dragging something. The Handleevent () function handles all three mouse time in the drag-and-drop function. It first obtains a reference to the event object and the target of the events. After that, use a switch statement to determine which event style to trigger. When the MouseDown time occurs, the target's class is checked for the "Draggable" class, and if so, the target is stored in the dragging. This technique makes it easy to determine which elements can be dragged by markup language rather than JavaScript script.
The MouseMove of Handleevent () is the same as the previous code, but check to see if dragging is null. When it is not NULL, it is known that dragging is the element to be dragged, so that it is placed in the right place. The MouseUp situation simply resets the dragging to null to invalidate the judgment in the MouseMove event.
DragDrop also has two public methods: Enable () and disable (), which simply add and remove all event handlers accordingly. These two functions provide additional control over the drag-and-drop function.
To use the DragDrop object, go to ouch to include the Code on the page and Invoke enable (). Drag-and-drop is automatically enabled for all elements that contain the "draggable" class, as shown in the following example:
<div class= "draggable" style= "Position:absolute; Background:red "></div>
Note that for the element to be dragged, it must be absolutely positioned.
Repair Drag function
When you try the above example, you will find that the upper-left corner of the element is always with the pointer. The result is a bit uncomfortable for the user because when the mouse starts to move, the element seems to jump suddenly. Ideally, the action should look as if the element was "picked up" by the pointer, meaning that when the element was dragged, the point that the user clicked was where the pointer should remain.
To achieve the desired effect, some additional calculations must be done. You need to compute the difference between the upper-left corner of the element and the position of the pointer. This difference should be determined at the time the MouseDown event occurs and remains until the MouseUp event occurs. By comparing the Clientx and Clienty properties of the event with the Offsetleft and offsettop properties of the element, you can figure out how much space is required in both horizontal and vertical directions.
To save the difference on the x and Y coordinates, you need several variables. DIFFX and Diffy These variables need to be used in the OnMouseMove event handler to properly position the elements, as shown in the following example:
var DragDrop = function () {var dragging = null;
var diffx = 0;
var diffy = 0;
function Handleevent (event) {//get events and targets = Eventutil.getevent (event);
var target = Eventutil.gettarget (event); Determine the event type switch (event.type) {case "MouseDown": if (target.className.indexOf ("Dra
Ggable ") >-1) {dragging = target;
DIFFX = Event.clientx-target.offsetleft;
Diffy = Event.clienty-target.offsettop;
} break; Case "MouseMove": if (dragging!== null) {//Get event events = Eventuti
L.getevent (event);
Specify Position Dragging.style.left = (EVENT.CLIENTX-DIFFX) + "px";
Dragging.style.top = (Event.clienty-diffy) + "px";
} break; Case "MouseUp": dragging = null;
Break
}
}; Public interface Return {enable:function () {Eventutil.addhandler (document, "MouseDown", hand
Leevent);
Eventutil.addhandler (document, "MouseMove", handleevent);
Eventutil.addhandler (document, "MouseUp", handleevent);
}, Disable:function () {Eventutil.removehandler (document, "MouseDown", handleevent);
Eventutil.removehandler (document, "MouseMove", handleevent);
Eventutil.removehandler (document, "MouseUp", handleevent);
}
}
}(); Enable drag-and-drop dragdrop.enable ();
Adding custom events
The drag-and-drop function is not really applied until you know when the drag and drop starts. From this point of view, the preceding code does not provide any means for dragging to start, dragging, or ending. At this point, you can use custom events to indicate the occurrence of these events, so that other parts of the application interact with the drag function.
Because the DragDrop object is a single example that uses a module pattern, you need to make some changes to use the Eventtarget type. First, create a new Eventtarget object, then add the Enable () and disable () methods, and finally return the object. Take a look at the content:
This code defines 3 events: DragStart, drag, and Dragend. They all set the dragged elements to target and give the X and Y properties to represent the current position. They trigger on the DragDrop object, and then add the Enable () and disable () methods to the object before returning the object. The small changes in these module patterns enable the DragDrop object to support the event, as follows:
var eventutil = {Getevent:function (event) {return event? event:window.event;
}, Gettarget:function (event) {return event.target event.srcelement; }, Addhandler:function (element, type, handler) {if (Element.addeventlistener) {Element.addeven
Tlistener (type, handler, false);
else if (element.attachevent) {element.attachevent ("on" + type, handler);
else {element["on" + type] = handler; }, Removehandler:function (element, type, handler) {if (Element.removeeventlistener) {ele
Ment.removeeventlistener (type, handler, false);
else if (element.detachevent) {element.detachevent ("on" + type, handler);
else {element["on" + type] = NULL;
}
}
};
function Eventtarget () {this.handlers = {};} Eventtarget.prototype = {constructor:eventtarget, addhandler:function (type, HandlER) {if (typeof this.handlers[type] = = "undefined") {This.handlers[type] = [];
} this.handlers[type].push (handler);
}, Fire:function (event) {if (!event.target) {event.target = this;
} if (This.handlers[event.type] instanceof Array) {var handlers = This.handlers[event.type];
for (var i = 0, len = handlers.length i < len; i++) {Handlers[i] (event);
}}, Removehandler:function (type, handler) {if (this.handlers[type) instanceof Array) {
var handlers = This.handlers[type];
for (var i = 0, len = handlers.length i < len; i++) {if (handlers[i] = = handler) {
Break
} handlers.splice (I, 1);
}
}
};
var DragDrop = function () {var DragDrop = new Eventtarget ();
var dragging = null;var diffx = 0;
var diffy = 0;
function Handleevent (event) {//get events and targets = Eventutil.getevent (event);
var target = Eventutil.gettarget (event); Determine the event type switch (event.type) {case "MouseDown": if (target.className.indexOf ("Dra
Ggable ") >-1) {dragging = target;
DIFFX = Event.clientx-target.offsetleft;
Diffy = Event.clienty-target.offsettop;
Dragdrop.fire ({type: "DragStart", target:dragging,
X:event.clientx, y:event.clienty});
} break; Case "MouseMove": if (dragging!== null) {//Get event events = Eventut
Il.getevent (event); Specify Location Dragging.styLe.left = (EVENT.CLIENTX-DIFFX) + "px";
Dragging.style.top = (Event.clienty-diffy) + "px"; Triggers the custom event Dragdrop.fire ({type: drag), Target:draggi
Ng, X:event.clientx, y:event.clienty});
} break;
Case "MouseUp": Dragdrop.fire ({type: "Dragend", target:dragging,
X:event.clientx, y:event.clienty});
dragging = null;
Break
}
};
public interface dragdrop.enable = function () {Eventutil.addhandler (document, "MouseDown", handleevent);
Eventutil.addhandler (document, "MouseMove", handleevent);
Eventutil.addhandler (document, "MouseUp", handleevent);
}; dragdrop.disabled = function () {Eventutil.removehandler (document, "MouseDown", handleevent);
Eventutil.removehandler (document, "MouseMove", handleevent);
Eventutil.removehandler (document, "MouseUp", handleevent);
return dragdrop;
}();
Enable drag-and-drop dragdrop.enable ();
Dragdrop.addhandler ("DragStart", function (event) {var status = document.getElementById ("status");
status.innerhtml = "Started dragging" + event.target.id;});
Dragdrop.addhandler ("Drag", function (event) {var status = document.getElementById ("status");
status.innerhtml + + "<br/>dragged" + event.target.id + to ("+ Event.x +", "+ Event.y +") ";});
Dragdrop.addhandler ("Dragend", function (event) {var status = document.getElementById ("status"); status.innerhtml + + "<br/>dragged" + Event.target.id + "at (" + Event.x + "," + Event.y + ")";});
Here, an event handler is added for each event of the DragDrop object. It also uses an element to implement the current state and position of the dragged element. Once the element is dropped, you can see all the intermediate steps that have elapsed since it was first dragged.
Adding custom events to DragDrop can make this object more robust, and it will be able to handle complex drag-and-drop functionality in network applications.