How to use javascript  to implement drag and drop

Source: Internet
Author: User

JavaScript is good at modifying DOM elements in a page, but using JavaScript usually only implements some simple features, such as the flip of a picture, a tab in a Web page, and so on. This article will show you how to implement drag-and-drop on the created elements in the page.

There are many reasons to add drag and drop functionality to your page, the simplest of which is to reorganize your 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 as 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 drag-and-drop functionality, as you can achieve!

The effect of dragging and dropping on your Web page is not very complex. First, we know where the mouse is, and then we need to know when the user clicked on an element so that we know we're ready to start dragging it, and finally we're going to move the element.

Capturing the movement of the mouse

The first step, we need to get the coordinates of the mouse, through a function and assign to Document.onmousemove can achieve this function:

Code
  1. Document.onmousemove = mouseMove;
  2. function mouseMove (EV) {
  3. ev = ev | |  window.event;
  4. var mousepos = mousecoords (EV );
  5. function mousecoords (EV) {
  6. if (ev.pagex | | Ev.pagey) {
  7. return { X:ev.pagex, y:  Ev.pagey};  
  8.  } 
  9. return {
  10. x:ev.clientx + document.body.scrollLeft - Document.body.clientLeft,
  11. y:ev.clienty + document.body.scrollTop - document.body.clientTop
  12.  };

First we need to explain the event object. No matter when you move, click the mouse, or press the key, and so on, an event will 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 this page action. Therefore, we make document.onmousemove pointer to the function that the mouse moves, the function that the mouse moves obtains the event object.

In the code above, 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 EV is empty so that it needs to be set to window.event.

We need to capture the coordinates of the mouse multiple times in this article, so we've written a mousecoords method that has a parameter: event.

We're going to 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 document documents. If you have a 500*500 window and the mouse is in the middle of the window, the values for both Pagex and Pagey will be 250. If you scroll the window down 500 pixels, the value of Pagey is 750.

In contrast, Microsoft's IE uses EVENT.CLIENTX and event.clienty to represent the position of the mouse relative to the window, rather than the current document. In the same example, if you place the mouse in the middle of the 500*500 window, both the Clientx and Clienty values will be 250. If you scroll down the page, Clienty will still be 250 because it is measured relative to the Windows window, not the current document. Therefore, in the mouse position, we should introduce the ScrollLeft and ScrollTop properties of the document body area. Finally, the document file in IE is not actually in (0,0) position, there is a small (usually 2px) border around it, Document.body.clientLeft and Document.body.clientTop contain the width of the border, and you need to introduce them in the mouse position.

Fortunately, now that we have the mousecoords function, we don't have to worry about getting the mouse position anymore.

Capturing a mouse click

Next, we must know when the mouse clicks and when to release. If we skip this step, as long as your mouse moves through these elements, it will produce the effect of dragging these elements, which is annoying and violates human intuition.

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 point to the function. If we let Document.onmousedown point to a function, then this function will be executed because the mouse clicks on any element: text, images, tables, and so on. We just want the specific elements in the page to have the ability to drag and drop, so we can do this in the following ways:

Code
    1. document.onmouseup  =  mouseup;   
    2. var  dragobject  =  null ;    
    3. function  makeclickable (object)   {   
    4.     object.onmousedown  =  function ()   {   
    5.     dragobject  =  this ;    
    6.     }   
    7. }   
    8. function  mouseUp (EV)   {   
    9.     dragobject  =  null ;    
    10. }   

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

Moving elements

We now know how to capture mouse movement and click. The next thing to do is move any element that we want to drag. First, move an element exactly to the position we want on the page, the position value of the element style sheet must be absolute, This means that you can set its style.top or style.left, and the measured value is relative to the upper-left corner of the page, because all of our mouse movements are in relation to the upper-left corner of the page, which is usually the case.

Once we set the item.style.position= ' absolute ', the next step is to change the position of the element top and left to make it move!

Code
  1. Document.onmousemove = mouseMove;
  2. Document.onmouseup = mouseUp;
  3. var dragobject = null ;  
  4. var mouseoffset = null ;  
  5. function getmouseoffset (target, ev) {
  6. ev = ev | |  window.event;
  7. var docpos = getPosition (target );
  8. var mousepos = mousecoords (EV );
  9. return {x:mousepos.x - docpos.x,   y:mousepos.y - docpos.y} ;  
  10. function getPosition (e) {
  11. var left = 0 ;  
  12. var top = 0 ;  
  13. While (e.offsetparent ) {
  14. left + = e.offsetleft;
  15. top + = e.offsettop;
  16. e = e.offsetparent;
  17.  } 
  18. left + = e.offsetleft;
  19. Top + = e.offsettop;
  20. return {x:left, y:top} ;  
  21. function mouseMove (EV) {
  22. ev = ev | |  window.event;
  23. var mousepos = mousecoords (EV );
  24. if (dragobject) {
  25. dragObject.style.position = ' absolute ';
  26. dragObject.style.top = mousepos.y -   Mouseoffset.y;
  27. dragObject.style.left = mousepos.x -   mouseoffset.x;
  28. return false;  
  29.  } 
  30. function mouseUp () {
  31. dragobject = null ;  
  32. function makedraggable (item) {
  33. if (!item) return;  
  34. item.onmousedown = function (ev ) {
  35. dragobject = this  ;  
  36. mouseoffset = Getmouseoffset (this   , ev);  
  37. return false  ;  
  38.  } 

You will notice that the code is based on our previous examples (refer to the previous article) and put them together, and you will be able to move the elements arbitrarily.

When we click on an element, another variable is stored, Mouseoffset. Mouseoffset simply contains the location information of the element we clicked on. If we have a 20*20px image and then click in the middle of the image, Mouseoffset should be {x:10,y:10}. If we click on the upper-left corner of the image, Mouseoffset should be {x:0,y:0}. We use it in the position information after the mouse moves. 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 a different function getposition. The getposition purpose 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 will get the position of the element relative to its parent element, not the document. In our script, all elements are relative to document documents, so you need to do so.

To complete the work of getting an element relative to the document location, GetPosition starts with its own parent, loops through its left and top values and accumulates, so we get the cumulative value of the element we want from the top and left of the document.

When we get this message and move the mouse, MouseMove starts to run. First we need to make sure that the Item.style.position value is absolute, and then we move the element anywhere, and the mouse position subtracts the offset of the mouse relative to the element that we recorded earlier. When the mouse is released, Dragobject is set to null, and the MouseMove function doesn't do anything anymore.

Placing elements

Our previous example has dealt with this problem by simply dragging an element and then putting it down. Then, there are usually other purposes when we drop the element, we take the drag element to the garbage bin as an example, or we might want to align the element with a particular area of the page.

Unfortunately, we have entered a relatively major issue here. Because the element we are moving is always directly under our mouse, it is not possible to trigger MouseOver, MouseDown, MouseUp, or mouse actions on other elements of the page. If you move an element to the garbage collector, your mouse will always move above the element, not the garbage collection station.

So how do we deal with this problem? Here are some solutions. The purpose of the Mouseoffset mentioned above is to ensure that the element is always in the correct position under the mouse, if you neglect this, then always make the element at the bottom right of the mouse, your mouse will not be hidden by the element you are dragging, we will not encounter problems. But in fact often does not, in order to be beautiful we usually want to keep the element under the mouse.

Another option is to not move the element you are dragging, and 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 the same problem as the previous one: aesthetics.

Our final solution does not affect the elements 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 targets that we want to place, and when the mouse is released, we manually check the current mouse position relative to each target to see if the mouse is released at the target position in this goal, and if so, we know we have placed the element on our target.

Code
  1.    
  2. var droptargets = [];
  3. function adddroptarget (droptarget) {
  4. Droptargets.push (droptarget );
  5. function mouseUp (EV) {
  6. ev = ev | |  window.event;
  7. var mousepos = mousecoords (EV );
  8. for (var i = 0;  i < Droptargets.length; i + + ) {
  9. var curtarget = droptargets[i];
  10. var targpos = getPosition (curtarget)  ;
  11. var targwidth = parseint (  Curtarget.offsetwidth);
  12. var targheight = parseint (  Curtarget.offsetheight);
  13. if (
  14. (mousepos.x > targpos.x) &&
  15. ( mousepos . < (targpos.x + targwidth)) &&  
  16. (mousepos.y > TARGPOS.Y) &&
  17. (mousepos.y < (targpos.y + targheight)) {
  18. // dragobject Was dropped onto curtarget!   
  19.    } 
  20.  } 
  21. dragobject =  /c45>null ;  

In this example, when the mouse is released, we loop each target that might place the element, and if the mouse pointer is on the target, we have an event to place the element, with the mouse horizontal axis greater than the left horizontal axis of the target element (mousepos.x> Targpos.x), which is less than the right horizontal axis of the target element (mousepos.x< (Targpos.x+targwidth)) to determine 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 functions

Finally, we use all the code snippets to create a complete drag-and-drop function script. The first thing we want to do is DOM operations, and if you're not very 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 re-plan 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 pseudo-code to walk through the steps and leave the real code to the reader in the form of annotations.

1. When the document is loaded for the first time, we create a div tag named DragHelper, and when we start moving an element, DragHelper becomes a hidden element that can be moved around. The real elements are not dragged, just using insertbefore and a to move. We hid the draghelper at the beginning.

2. We create the 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 collection that allows the elements to move freely between these containers. The elements in each container are also bound together by the Setattribute,createdragcontainer function.

4. Now that our code knows the collection where each element resides, let's look at the MouseMove function. The MouseMove function first sets a variable target, which represents the target element below the mouse, and if the element is in the collection (judged by getattribute) proceed as follows:

4.1. First, when necessary, we run a simple script to change the class attribute of the target element, creating a flip effect.

4.2. Then we check if the mouse is clicked (because our code is already running here), if the event occurs:

4.2.1. Sets the variable curtarget to the current element.
4.2.2. Record the position of the element currently 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 fully have a backup of the drag element, which is always under the mouse, we must remove the Dragobj property so that the code knows that Dragobj is not in the collection.
4.2.5. We quickly record the current position, width, and height of each element in the collection. When the element first starts being dragged, we only need to do it once, otherwise we have to do it once when the mouse moves, or even hundreds of times in a second.

4.3. If the mouse is not clicked, 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 well as the elements created earlier in the article.

5.2. We then check to see if 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.
5.2.2. Then we place the dragged element in front of another element in the container, or at the last position of the container.
5.2.3. Finally we determine that the element is visible.

6. The remaining thing is to capture the MouseUp event:
6.1. First you need to hide the DragHelper: it is no longer needed because we are not dragging 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 will put it back where it originally was.

How to use javascript&nbsp; to implement drag and drop

Related Article

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.