JavaScript drag-and-drop effect to implement code _javascript techniques

Source: Internet
Author: User
Tags documentation garbage collection new set
There are many reasons why you can add a drag-and-drop function to your page, the simplest reason being to rearrange the data. For example, you might want users to be able to reorganize a series of page elements by placing an input or select component next to each element to represent their order as a solution so that the group element can be dragged and dropped is an alternative. Or maybe you want to have a navigation window on the site that can be moved by the user. These are simple reasons to use the drag-and-drop feature, because you can achieve it!
Implementing drag-and-drop on your Web page is not very complicated. First, we know where the mouse is, and then we need to know when the user clicks on an element so that we know we're ready to start dragging it, and finally we're going to move this element.

Capturing the movement of the mouse
In the first step, we need to get the coordinates of the mouse, which can be achieved by assigning a function to Document.onmousemove:

Code
Copy Code code as follows:

Document.onmousemove = MouseMove;
function MouseMove (EV) {
EV = EV | | window.event;
var mousepos = mousecoords (EV);
}
function Mousecoords (EV) {
if (Ev.pagex | | ev.pagey) {
return {x:ev.pagex, y:ev.pagey};
}
return {
X:ev.clientx + Document.body.scrollleft-document.body.clientleft,
Y:ev.clienty + document.body.scrolltop-document.body.clienttop
};
}

First we need to explain the event object. No matter when you move, click the mouse, or press the button, an event can occur. In IE, this event is global, it is stored in window.event, and for Firefox, and other browsers, this event will be passed to any function that points to the page action. So we make the document.onmousemove point to the mouse-moving function, and the mouse-moving function Gets the event object.
In the above code, the EV contains the event object in all browser environments. In Firefox, "| | Window.event "will be ignored because it already contains events. In IE, the value of the EV is empty so that it needs to set its value to window.event.
In this article we need to capture the coordinates of the mouse more than once, so we write a mousecoords method that has a parameter: event.
We'll discuss the differences between IE and other browsers again. Firefox and other browsers use Event.pagex and Event.pagey to represent the location of the mouse relative to the documents document. If you have a 500*500 window and the mouse is in the middle of the window, the Pagex and Pagey values will all be 250. If you scroll the window down by 500 pixels, the Pagey value is 750.
On the contrary, Microsoft's IE uses EVENT.CLIENTX and event.clienty to indicate the location of the mouse relative to window windows, rather than the current document documents. In the same example, if you place the mouse in the middle of the 500*500 window, the Clientx and Clienty values will all be 250. If you scroll down the page, the clienty will still be 250 because it is measured relative to the Windows window, not the current document documentation. Therefore, in the mouse position, we should introduce the ScrollLeft and ScrollTop properties of the body area of document documents. Finally, the document file in IE is not actually in the position of (0,0), and there is a small (usually 2px) border around it, Document.body.clientLeft and Document.body.clientTop contain the width of the border, which also needs to be introduced into the mouse position.
Luckily, now that we have the mousecoords function, we don't have to worry about getting the mouse position anymore.

Capture the mouse click
Next, we must know when the mouse clicks and when it is released. If we skip this step, as long as your mouse moves through these elements, it will create the effect of dragging these elements, which is annoying and counterintuitive.
Here, there are two functions that can help us: onmousedown and onmouseup. We have previously pointed document.onmousemove to a function, so it seems logical that both Document.onmousedown and Document.onmouseup should be directed to functions. If we let Document.onmousedown point to a function, then this function will be executed by clicking on any element of the mouse: text, images, tables, and so on. We just want a specific element on the page to have a drag-and-drop function, so we can do it in the following ways:

Code
Copy Code code as follows:

Document.onmouseup = mouseUp;
var dragobject = null;
function Makeclickable (object) {
Object.onmousedown = function () {
Dragobject = this;
}
}
function mouseUp (EV) {
Dragobject = null;
}

We now have a variable dragobject that contains any elements you click. When you release the mouse, the dragobject is set to NULL, so that when the dragobject is not empty, we need to do a drag operation.

Moving elements
We now know how to capture mouse movements and clicks. The next thing to do is to move any element that we want to drag. First, move an element exactly to where we want it on the page, and the position value of the stylesheet must be absolute, This means that you can set its style.top or style.left, measured relative to the upper-left corner of the page, because all of our mouse moves are in relation to the upper-left corner of the page, usually.
Once we set the item.style.position= ' absolute ', then we need to change the top and left position of the element to make it move!

Code
Copy Code code as follows:

Document.onmousemove = MouseMove;
Document.onmouseup = mouseUp;
var dragobject = null;
var mouseoffset = null;
function Getmouseoffset (target, Ev) {
EV = EV | | window.event;
var docpos = getPosition (target);
var mousepos = mousecoords (EV);
return {x:mousepos.x-docpos.x, y:mousepos.y-docpos.y};
}
function GetPosition (e) {
var left = 0;
var top = 0;
while (e.offsetparent) {
Left + + E.offsetleft;
Top + = E.offsettop;
e = e.offsetparent;
}
Left + + E.offsetleft;
Top + = E.offsettop;
return {x:left, y:top};
}
function MouseMove (EV) {
EV = EV | | window.event;
var mousepos = mousecoords (EV);
if (dragobject) {
dragObject.style.position = ' absolute ';
DragObject.style.top = Mousepos.y-mouseoffset.y;
DragObject.style.left = Mousepos.x-mouseoffset.x;
return false;
}
}
function MouseUp () {
Dragobject = null;
}
function Makedraggable (item) {
if (!item) return;
Item.onmousedown = function (EV) {
Dragobject = this;
Mouseoffset = Getmouseoffset (this, EV);
return false;
}
}

You'll notice that the code is based on our previous example (refer to the previous article), put them together, and you'll be able to move the elements at random.
When we click on an element, we store another variable, mouseoffset. Mouseoffset simply contains the location information of the click Element. If we have a 20*20px image and click in the middle of the image, Mouseoffset should be {x:10, y:10}. If we click on the top left corner of the image, Mouseoffset should be {x:0, y:0}. We use it in the position information after the mouse is moved. If we don't store this value, the position of the element relative to the mouse will be the same regardless of where you click on the element.
The Mouseoffset function uses another function getposition. The purpose of the getposition is to return the coordinate position of the element relative to the DOCUMEMT document. If we simply read Item.offsetleft or item.style.left, we get the position of the element relative to its parent element, not the document documentation. In our script, all elements are relative to document documents, so it is necessary to do so.
To complete the work of getting the element relative to the document's location, GetPosition starts with its own parent, loops through its left and top values, and accumulates, so that we get the cumulative value of the element that we want to be from the front of the document and the left-hand side.
When we get this message and move the mouse, MouseMove starts to run. First we need to ensure that the Item.style.position value is absolute, and then we move the element anywhere, and the mouse position subtracts the mouse's offset from the element we previously recorded. When the mouse is released, the dragobject is set to null, and the MouseMove function no longer does anything.

Drop element
Our previous example has dealt with this problem by simply dragging an element and then putting it down. Then, when we put down the element, there are usually other purposes, we take the element to the garbage collector as an example, or we might want to align that element with a particular region in the page.
Unfortunately, we have entered a relatively major problem here. Because the elements we are moving are always directly under our mouse, it is not possible to raise MouseOver, MouseDown, MouseUp, or mouse actions on other elements of the page. If you move an element to the garbage collection station, your mouse will always be above the moving element, not the garbage collector.
So how do we deal with this problem? Here are a few solutions. The purpose of the Mouseoffset mentioned above is to ensure that the element is always in the right position under the mouse, and if you ignore this and then always make the element at the bottom right of the mouse, your mouse will not be hidden by the element you are dragging, nor will we encounter problems. But in fact it's not always the case, for the sake of beauty we usually keep the element underneath the mouse.
Another option is to not move the element you are dragging, you can change the mouse style to tell the user that you are dragging an element until you place it somewhere. This solves our problem, but brings us to the same problem as the previous one: aesthetics.
Our final solution does not affect the elements that you are moving, nor does it affect the elements at the end of the move (such as the garbage collection station). Unfortunately, this is much more difficult than the previous two solutions. What we're going to do is get a set of goals that we're going to place, when the mouse is released, we manually check the current mouse position relative to each target to see if the mouse is released in the position of a target in this target, if yes, we know we have placed the element on our target.

Code
Copy Code code as follows:

/*
All code from the previous example are needed with the exception
of the MOUSEUP function which is replaced below
*/
var droptargets = [];
function Adddroptarget (droptarget) {
Droptargets.push (DropTarget);
}
function mouseUp (EV) {
EV = EV | | window.event;
var mousepos = mousecoords (EV);
for (var i = 0; i < droptargets.length i + +) {
var curtarget = droptargets[i];
var targpos = getPosition (curtarget);
var targwidth = parseint (curtarget.offsetwidth);
var targheight = parseint (curtarget.offsetheight);
if (
(Mousepos.x > Targpos.x) &&
(Mousepos. < (targpos.x + targwidth)) &&
(Mousepos.y > Targpos.y) &&
(Mousepos.y < (targpos.y + targheight)) {
Dragobject was dropped onto curtarget!
}
}
Dragobject = null;
}


In this example, when the mouse is released, we loop the target of each possible element, and if the mouse pointer is on the target, we have an event to place the element, and the mouse axis is larger than the left horizontal axis of the target element (mousepos.x> targpos.x), is smaller than the right horizontal axis of the target element (mousepos.x< (targpos.x+ targwidth)) to determine, for the y-coordinate we make the same judgment. If all of these values return True, then our mouse is within the range of the target element.

Integrate all the features
Finally, we use all the code snippets to create a complete drag-and-drop function script. The first thing we have to do is DOM operations, and if you're not quite familiar with it, you can read JavaScript Primer on DOM manipulation.
The next code creates containers and container groups so that each element can be dragged in these containers, which is done on the basis of the second demo in this article. This code can be used to rearrange the order of elements, place the navigation window on the left or right side of the page, or add other features that you can think of.
We'll use pseudocode to explain it step-by-step, leaving the real code in the comments way for the reader to see.
1. When the document is first loaded, we create a div tag named DragHelper, and when we start moving an element, DragHelper becomes a hidden element that can move around. The real elements are not dragged and are only moved using InsertBefore and appendchild. We hide DragHelper at the beginning.
2. We create MouseDown and MouseUp functions. At first, all of these functions assume that the state of the mouse button is recorded, so that the Imousedown variable is true when the mouse is pressed and false when it is not pressed.
3. We create a global variable dragdrops, and a function Createdragcontainer. Dragdrops contains a set of interrelated containers. Any variable passed into the Createdragcontainer (representing the container) is organized into a new set that allows elements to move freely between the containers. The elements in each container are also bound together by the Setattribute,createdragcontainer function.
4. Now our code knows the collection of each element, now look at the MouseMove function. The MouseMove function first sets a variable target to represent the target element below the mouse, and if the element is in the collection (judged by the getattribute), the following operation continues:
4.1. First, when necessary, we run a simple script to change the class attribute of the target element, thus creating a flip effect.
4.2. Then we check whether the mouse clicks (because our code has run to here), if the event occurs:
4.2.1. Set variable curtarget to the current element.
4.2.2. Record the current position of the element in the document so that its value can be retrieved when needed.
4.2.3. Cloning the current element to DragHelper allows us to move the hidden backup of the element.
4.2.4. Because in DragHelper we completely have a backup of the drag element, which is always under the mouse, we have to remove the Dragobj attribute so that the code knows that Dragobj is no longer in the collection.
4.2.5. We quickly record the current position, width, and height of each element in the collection. When the element is first dragged, we only have to do it once, or we will have to do it once, or even hundreds of times in a second, every time the mouse moves.
4.3. If the mouse does not click, either we have the same target element as before, or there is no target element, we will not do anything in either case.
5. Now we check the Curtarget variable. Curtarget should contain only one dragged object, so if it exists, it means that we are dragging an element:
5.1. Move the hidden div to the mouse, which can be dragged as the element created earlier in the article.
5.2. Then we check whether the mouse exists in each container in the current collection.
5.2.1. If the mouse is in a container, we examine each element in the container to see where the element we are dragging belongs to.
5.2.2. Then we place the dragged element in front of another element in the container, or the last position of the container.
5.2.3. Finally we make sure that the elements are visible.
6. The remaining thing is capturing the MouseUp event:
6.1. First need to hide DragHelper: it is no longer needed because we have not dragged anything.
6.2. If the dragged element is visible, it already exists in any container to which it belongs, and all work is completed.
6.3. If the dragged element is not visible, we put it back where it used to be.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.