JS drag and Drop plug-in implementation steps _javascript skills

Source: Internet
Author: User

This article details the JS drag-and-drop plug-in implementation steps, mainly from the following six steps to do detailed analysis, the specific contents are as follows:

One, JS drag-and-drop plug-in principle
Second, according to the principle to achieve the most basic effect
Third, Code abstraction and optimization
Iv. Expansion: Effective drag-and-drop elements
V. Performance Optimization and Summary
Six, jquery Plug-ins
JS Drag is a common web page effect, this article will start from zero to implement a simple JS plug-in.


One, JS drag-and-drop plug-in principle
What is the common drag-and-drop operation? There are probably several steps to the entire process:

1, with the mouse click dragged elements

2, hold the mouse, move the mouse

3, drag and drop elements to a certain position, release the mouse

The process here involves three DOM events: Onmousedown,onmousemove,onmouseup. So the basic idea of dragging is:

1, with the mouse click dragged by the elements trigger onmousedown

(1) To set the drag of the current element to true, indicating that you can drag

(2) record the coordinates of the current mouse x,y

(3) record the coordinates of the current element x,y

  2. Move mouse to trigger onmousemove

(1) To determine whether the element can be dragged, if it is to enter step 2, or directly return

(2) If the element can be dragged, set the coordinates of the element

The x-coordinate of the element = the horizontal distance of the mouse movement + the element's original X coordinate = the mouse's current x-coordinates-the x-coordinates before the mouse and the x-coordinates of the elements

The y-coordinate of the element = the horizontal distance of the mouse movement + the element's original y-coordinate = the mouse's y-coordinate before the y-coordinate of the mouse and the y-coordinate of the element

3, release the mouse trigger onmouseup

(1) Set the mouse drag state to False

Back to the top of
second, according to the principle to achieve the most basic effect
There are a few things to note before you can achieve basic results:

  1, the element wants to be dragged, its postion attribute must be relative or absolute

  2, through Event.clientx and Event.clienty to get the coordinates of the mouse

3. OnMouseMove is bound to the document element rather than dragging the element itself, which solves the problem of delay or stop movement caused by a quick drag

The code is as follows:

var dragobj = document.getElementById ("test");
   DragObj.style.left = "px";
   DragObj.style.top = "px";
 
   var mousex, Mousey, OBJX, objy;
   var dragging = false;
 
   Dragobj.onmousedown = function (event) {
    event = Event | | window.event;
 
    dragging = true;
    DragObj.style.position = "relative";
 
 
    MouseX = Event.clientx;
    Mousey = Event.clienty;
    OBJX = parseint (dragObj.style.left);
    Objy = parseint (dragObj.style.top);
   }
 
   Document.onmousemove = function (event) {
    event = Event | | window.event;
    if (dragging) {
 
     dragObj.style.left = parseint (Event.clientx-mousex + objx) + "px";
     DragObj.style.top = parseint (Event.clienty-mousey + objy) + "px";
    }
 
   Document.onmouseup = function () {
    dragging = false;
   }


Third, Code abstraction and optimization
The above code to make plug-ins, to abstract them out, the basic structure is as follows:

Copy Code code as follows:

; (Function (window, undefined) {

function Drag (ele) {}

Window. Drag = Drag;
}) (window, undefined);

The code is wrapped with a self executing anonymous function, internally defining the drag method and exposing it to the global, directly calling drag, and passing in the dragged element.

First, the simple encapsulation of some common methods:

; (Function (window, undefined) {
    var dom = {
     //binding event
     on:function (node, eventName, handler) {
      if (node.adde Ventlistener) {
       Node.addeventlistener (eventName, handler);
      }
      else {
       node.attachevent ("on" + EventName, handler);
      }
     },
     //Get the style of the element
     getstyle:function node, StyleName) {
      var realstyle = null;
      if (window.getComputedStyle) {
       Realstyle = window.getcomputedstyle (node, null) [StyleName];
      }
      else if (node.currentstyle) {
       realstyle = Node.currentstyle[stylename];
      }
      Return Realstyle
     },
     //Get style of setting element
     setcss:function (node, CSS) {for
      (var key in CSS) {
       Node.style[key] = Css[key];}}
    ;
    Window. Drag = Drag;
   }) (window, undefined);

In a drag-and-drop operation, there are two objects: the object being dragged and the mouse object, and we define the following two objects and their corresponding actions:

The first drag object that contains an element node and the coordinates x and y before dragging:

 function dragelement (node) {
     This.node = node;//dragged element node
     this.x =//drag before x coordinate
     this.y =//drag before y-coordinate
    }
    Dragelement.prototype = {
     constructor:dragelement,
     init:function () {     
      this.setelecss ({
       "left") : Dom.getstyle (node, "left"),
       ' top ': Dom.getstyle (node, top)
      })
      . SetXY (Node.style.left, node.style.top);
     },
     //Set the current coordinate
     setxy:function (x, y) {
      this.x = parseint (x) | |;
      This.y = parseint (y) | | ;
      return this;
     },
     //Set the style of the element node
     setelecss:function (CSS) {
      dom.setcss (This.node, CSS);
      return this;
     }
    

Another object is the mouse, which contains the x and y coordinates:

function Mouse () {
     this.x =;
     This.y =;
    }
    Mouse.prototype.setXY = function (x, y) {
     this.x = parseint (x);
     This.y = parseint (y);
    }  

This is the two objects defined in the drag-and-drop operation.

If a page can have multiple drag-and-drop elements, what should be noted:

1, each element corresponding to a Drag object instance

2, each page can only have a drag in the element

To do this, we define a single object to save the associated configuration:

Copy Code code as follows:

var draggableconfig = {
ZIndex:,
Draggingobj:null,
Mouse:new Mouse ()
};

There are three properties in this object:

(1) ZIndex: The ZIndex property that is used to assign values to the drag-and-drop object, when two drag objects overlap, causing the current drag-and-drop object to be blocked, by setting the ZIndex to appear at the top level

(2) Draggingobj: Used to save the object being dragged, here remove the front used to determine whether the drag variable, through the Draggingobj to determine whether the current can be dragged and get the corresponding drag object

(3) Mouse: A unique mouse object used to save information such as the coordinates of the current mouse

Finally, bind the Onmousedown,onmouseover,onmouseout event, and consolidate the above code as follows:

 ; (Function (window, undefined) {var dom = {//binding event On:function (node, eventName, handler) {if node.
      AddEventListener) {Node.addeventlistener (eventName, handler);
      else {node.attachevent ("on" + EventName, handler);
      },//Get the style of the element getstyle:function (node, stylename) {var realstyle = null;
      if (window.getcomputedstyle) {Realstyle = window.getcomputedstyle (node, null) [StyleName];
      else if (node.currentstyle) {realstyle = Node.currentstyle[stylename];
     return realstyle;
      },//Gets the style of the setting element setcss:function (node, CSS) {for (var key in CSS) {Node.style[key] = Css[key];
    }
     }
    };
     #region drag element class function dragelement (node) {this.node = node;
     This.x =;
    This.y =;
       } Dragelement.prototype = {constructor:dragelement, init:function () {this.setelecss ({ "Left": dom.getstYLE (node, "left"), ' Top ': Dom.getstyle (node, top)}). SetXY (Node.style.left, node.style.top);
      }, Setxy:function (x, y) {this.x = parseint (x) | |; This.y = parseint (y) | |
      ;
     return this;
      }, Setelecss:function (CSS) {dom.setcss (This.node, CSS);
     return this;
     }//#endregion//#region mouse element function Mouse () {this.x =;
    This.y =;
     } Mouse.prototype.setXY = function (x, y) {this.x = parseint (x);
    This.y = parseint (y);
    }//#endregion//drag-and-drop configuration var draggableconfig = {zindex:, draggingobj:null, Mouse:new Mouse ()
    };
     function Drag (ele) {this.ele = Ele;
      function MouseDown (event) {var ele = Event.target | | event.srcelement;
      DraggableConfig.mouse.setXY (Event.clientx, Event.clienty);
      Draggableconfig.draggingobj = new Dragelement (ele); Draggableconfig.draggingobj SetXY (Ele.style.left, ele.style.top). setelecss ({"ZIndex": draggableconfig.zindex++, "position": "relative"});
     } Ele.onselectstart = function () {//Prevent text in the dragged object from being selected to return false;
    } dom.on (Ele, "MouseDown", MouseDown); } dom.on (document, "MouseMove", function (event) {if (draggableconfig.draggingobj) {var mouse = Draggable
      Config.mouse, draggingobj = draggableconfig.draggingobj; Draggingobj.setelecss ({"Left": parseint (event.clientx-mouse.x + draggingobj.x) + "px", "Top": parseint (Ev
     Ent.clienty-mouse.y + draggingobj.y) + "px"});
    }) Dom.on (document, "MouseUp", function (event) {draggableconfig.draggingobj = null; }) window.
   Drag = Drag;
 }) (window, undefined);

Call method: Drag (document.getElementById ("obj"));

Note that in order to prevent text from being selected in the dragged element, return false through the Onselectstart event handler to handle the problem.


Iv. Expansion: Effective drag-and-drop elements
Some of our common drag-and-drop effects are likely to be this:

The top of the frame is able to drag and drop operation, the content area is not dragged, how to achieve this effect:

First, optimize the drag-and-drop element object as follows, adding a target element target, which means the dragged object, in the login box above, is the entire login window.

The drag element that is logged and set coordinates is the target element, but it is not a valid part of the entire part that is dragged. We add Class draggable in the HTML structure for the dragged active area to effectively drag regions:


Copy Code code as follows:

<div id= "obj" class= "dialog" style= "position:relative;left:px" >
<div class= "header draggable" >
Drag-and-drop valid elements
</div>
<div class= "Content" >
Drag objects
</div>
</div>

Then modify the drag method as follows:

 function drag (ele) {
  var dragnode = (Ele.queryselector (". draggable") | | ele);
  Dom.on (Dragnode, "MouseDown", function (event) {
   var dragelement = draggableconfig.dragelement = new Dragelement (ele );

   DraggableConfig.mouse.setXY (Event.clientx, event.clienty);
   Draggableconfig.dragelement
    . SetXY (DragElement.target.style.left, DragElement.target.style.top)
    . Settargetcss ({
     "zindex": draggableconfig.zindex++,
     "position": "Relative"
    });
  On (Dragnode, "mouseover", function () {
   dom.setcss (this, draggablestyle.dragging);
  }). On (Dragnode, "mouseout", function () {
   dom.setcss (this, draggablestyle.defaults);}
  );
 

The main modification is that the bound MouseDown node becomes a valid element containing the Draggable class, and if Draggable is not included, the entire element is a valid element.


v. Performance optimization and Summary
Since onmousemove is being invoked, causing some performance problems, we can delay the binding onmousemove event by Settimout to improve the move function as follows

function Move (event) {
   if (draggableconfig.dragelement) {
    var mouse = draggableconfig.mouse,
     dragelement = draggableconfig.dragelement;
    Dragelement.settargetcss ({
     "left": parseint (event.clientx-mouse.x + dragelement.x) + "px",
     "Top": parseint ( Event.clienty-mouse.y + dragelement.y) + "px"
    });
 
    Dom.off (document, "MouseMove", move);
    settimeout (function () {
     Dom.on (document, "MouseMove", move);
    },);
   }
  

Summarize:

The implementation of the entire drag-and-drop plug-in is actually very simple, mainly to pay attention to a few

  1, realize the idea: the element drag position change is equal to the mouse to change the distance, the key is obtains the mouse the movement and the element original coordinates

2, through settimeout to delay loading onmousemove events to provide performance


Six, jquery plug-ins
Simply encapsulate it as a jquery plug-in, mostly related DOM methods that are replaced with jquery methods to manipulate

 ;
 
   (Function ($, window, undefined) {//#region drag element class function dragelement (node) {this.target = node;
   Node.onselectstart = function () {//Prevent the text in the dragged object from being selected to return false;
    } Dragelement.prototype = {constructor:dragelement, setxy:function (x, y) {this.x = parseint (x) | |; This.y = parseint (y) | |
    ;
   return this;
    }, Settargetcss:function (CSS) {$ (this.target). CSS (CSS);
   return this;
   }//#endregion//#region mouse element function Mouse () {this.x =;
  This.y =;
   } Mouse.prototype.setXY = function (x, y) {this.x = parseint (x);
  This.y = parseint (y);
 
  }//#endregion//drag-and-drop configuration var draggableconfig = {zindex:, dragelement:null, Mouse:new Mouse ()}; var Draggablestyle = {dragging: {cursor: ' move '}, defaults: {cursor: ' Default '}} var $docu
 
  ment = $ (document);
   function drag ($ele) {var $dragNode = $ele. Find (". draggable"); $dragNode = $dragNode. LenGth >?
   
 
   $dragNode: $ele; $dragNode. On ({"MouseDown": function (Event) {var dragelement = Draggableconfig.dragelement = new Dragelement ($e
 
     Le.get ());
     DraggableConfig.mouse.setXY (Event.clientx, Event.clienty); Draggableconfig.dragelement. SetXY (DragElement.target.style.left, DragElement.target.style.top). SETTARGETCSS (
    {"ZIndex": draggableconfig.zindex++, "position": "relative"});
    }, "MouseOver": Function () {$ (this). CSS (draggablestyle.dragging);
    }, "Mouseout": Function () {$ (this). CSS (draggablestyle.defaults); }} function Move (event) {if (draggableconfig.dragelement) {var mouse = Draggableconfig.mouse, D
    Ragelement = draggableconfig.dragelement; Dragelement.settargetcss ({"Left": parseint (event.clientx-mouse.x + dragelement.x) + "px", "Top": parseint (Eve
 
    Nt.clienty-mouse.y + dragelement.y) + "px"});
   $document. Off ("MouseMove", move); settimeout (function () {$document. On (' MouseMove ', move);
   }, );
   }} $document. On ({"MouseMove": Move, "MouseUp": function () {draggableconfig.dragelement = null;
 
  }
  });
  $.fn.drag = function (options) {drag (this);
 }) (JQuery, Windows, undefined)

The above is the JS drag-and-drop plug-in implementation steps in detail, I hope to help you.

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.