JavaScript Tutorial/Drag Drop/Drag Drop

Материал из Web эксперт
Перейти к: навигация, поиск

Simulated Drag And Drop with zEvents Library and zDragDrop Library

   <source lang="javascript">

<html>

   <head>
       <title>Simulated Drag And Drop Example</title>
       <script type="text/javascript">        

/*------------------------------------------------------------------------------

* JavaScript zEvents Library
* Version 1.1
* by Nicholas C. Zakas, http://www.nczonline.net/
* Copyright (c) 2004-2005 Nicholas C. Zakas. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
*------------------------------------------------------------------------------
*/  

/**

* Encapsulates information about an event.
* @scope public
* @class
*/

function zEvent() {

   /**
    * The type of event.
    * @scope public
    */
   this.type /*: String */   = null;
   
   /**
    * The object that caused the event.
    * @scope public
    */
   this.target /*: zEventTarget */ = null;
   
   /**
    * A secondary object related to the event.
    * @scope public
    */
   this.relatedTarget /*: zEventTarget */ = null;
   
   /**
    * Indicates whether or not the event can be canceled.
    * @scope public
    */
   this.cancelable /*: boolean */ = false;
   
   /**
    * The time that the event occurred.
    * @scope public
    */
   this.timeStamp /*: long */ = null;
   
   /*
    * Set to false to cancel event.
    * @scope public
    */
   this.returnValue /*: boolean */ = true;    

} /**

* Initializes the event object with information for the event.
* @scope public
* @param sType The type of event encapsulated by the object.
* @param bCancelable True if the event can be cancelled.
*/

zEvent.prototype.initEvent = function (sType /*: String */,

                                      bCancelable /*: boolean */) {
   this.type = sType;
   this.cancelable = bCancelable;
   this.timeStamp = (new Date()).getTime();

}; /**

* Prevents the default behavior for an event.
* @scope public
*/

zEvent.prototype.preventDefault = function () {

   if (this.cancelable) {
       this.returnValue = false;
   }

}; /**

* Any class that wants to support events should inherit from this.
* @class
* @scope public
*/

function zEventTarget() {

   /**
    * Array of event handlers.
    * @scope private
    */
   this.eventhandlers /*: Object */ = new Object();

} /**

* Adds an event listener function to handle the type of event.
* @scope public
* @param sType The type of event to handle (i.e., "mousemove", not "onmousemove").
* @param fnListener The listener function for the event.
*/

zEventTarget.prototype.addEventListener = function (sType /*: String */,

                                                   fnListener /*: Function */) {
   if (typeof this.eventhandlers[sType] == "undefined") {
       this.eventhandlers[sType] = new Array;
   }   
   
   this.eventhandlers[sType][this.eventhandlers[sType].length] = fnListener;                                                    

}; /**

* Causes an event to fire.
* @scope public
* @param oEvent The event object containing information about the event to fire.
* @return True if the event should continue, false if not.
*/

zEventTarget.prototype.dispatchEvent = function (oEvent /*: zEvent */) /*: boolean */ {

   /*
    * Set the target of the event.
    */
   oEvent.target = this;
   /*
    * Call each event handler and pass in the event object.
    */
   if (typeof this.eventhandlers[oEvent.type] != "undefined") {
       for (var i=0; i < this.eventhandlers[oEvent.type].length; i++) {    
           this.eventhandlers[oEvent.type][i](oEvent);
       }
   }
   /*
    * Return the value of returnValue, which is changed to false
    * when preventDefault() is called.
    */
   return oEvent.returnValue;                                                   

}; /**

* Removes an event listener function from handling the type of event.
* @scope public
* @param sType The type of event to remove from (i.e., "mousemove", not "onmousemove").
* @param fnListener The listener function to remove.
*/

zEventTarget.prototype.removeEventListener = function (sType /*: String */,

                                                      fnListener /*: Function */) {
   if (typeof this.eventhandlers[sType] != "undefined") {
       var arrTemp = new Array;
       for (var i=0; i < this.eventhandlers[sType].length; i++) {
           if (this.eventhandlers[sType][i] != fnListener) {
               arrTemp[arrTemp.length] = this.eventhandlers[sType][i];
           }
       }
       this.eventhandlers[sType] = arrTemp;
   }   
                                                  

};

       </script>        
       
       <script type="text/javascript">

/*------------------------------------------------------------------------------

* JavaScript zDragDrop Library
* Version 1.1
* by Nicholas C. Zakas, http://www.nczonline.net/
* Copyright (c) 2004-2005 Nicholas C. Zakas. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
*------------------------------------------------------------------------------
*/

/*

* This library requires the free zEvents library available from 
* http://www.nczonline.net/.
*/

/**

* Contains global settings and methods for drag and drop functionality.
* @scope public
*/

function zDrag() {} /**

* The item currently being dragged.
* @scope private
*/

zDrag.current /*: zDraggable */ = null; /**

* Indicates whether or not an item is being dragged.
* @scope private
*/

zDrag.dragging /*: boolean */ = false; /**

* Returns true if an item is being dragged.
* @scope public
* @return True if an item is being dragged, false if not.
* @type boolean
*/

zDrag.isDragging = function () /*: boolean */ {

   return this.dragging;

}; /**

* Sets the item being dragged.
* @scope protected
* @param {zDraggable} oDraggable The draggable item.
* @type void
*/

zDrag.setCurrent = function (oDraggable /*: zDraggable */) {

   this.current = oDraggable;
   this.dragging = true;

}; /**

* Returns the currently dragged item.
* @scope public
* @return The currently dragged item.
* @type zDraggable
*/

zDrag.getCurrent = function () /*: zDraggable */ {

   return this.current;

}; /**

* Clears the currently dragged item from memory and sets the dragging
* flag to false.
* @scope protected
* @type void
*/

zDrag.clearCurrent = function () {

   this.current = null;
   this.dragging = false;

}; /**

* Encapsulates the functionality for a draggable element.
* @scope public
* @extends zEventTarget
* @class
*/

function zDraggable(oElement, iConstraints) {

   /*
    * Inherit properties from zEventTarget.
    */
   zEventTarget.call(this);
   
   /*
    * Call constructor.
    */
   this.construct(oElement, iConstraints);  
   
   /**
    * The difference between the x cursor position and left edge of the element.
    * @scope private
    * @type int
    */  
   this.diffX /*: int */ = 0;
   
   /**
    * The difference between the y cursor position and top edge of the element.
    * @scope private
    * @type int
    */  
   this.diffY /*: int */ = 0;
   
   /**
    * Collection of drop targets for this item.
    * @scope private
    * @type Array
    */
   this.targets /*: Array */ = [];

} /*

* Inherit methods from zEventTarget.
*/

zDraggable.prototype = new zEventTarget; /**

* Indicates the dragged item can be dragged along the X axis.
* @scope public
* @type int
* @final
*/

zDraggable.DRAG_X /*: int */ = 1; /**

* Indicates the dragged item can be dragged along the Y axis.
* @scope public
* @type int
* @final
*/

zDraggable.DRAG_Y /*: int */ = 2; /**

* Adds a new drop target to the draggable item.
* @scope public
* @param {zDropTarget} oDropTarget The drop target to register for this item.
* @type void
*/

zDraggable.prototype.addDropTarget = function (oDropTarget /*: zDropTarget */) {

   this.targets.push(oDropTarget);

}; /**

* Creates a new instance based on the given element and the constraints.
* @scope private
* @constructor
* @param {HTMLElement} oElement The DOM element to make draggable.
* @param {int} iConstraints The rules for dragging.
*/

zDraggable.prototype.construct = function (oElement /*: HTMLElement */,

                                          iConstraints /*: int */) {
   /**
    * The element to make draggable.
    * @scope private
    * @type HTMLElement
    */
   this.element /*: HTMLElement */ = oElement;
   
   /**
    * The constraints indicating the rules for dragging.
    * @scope private
    * @type int
    */
   this.constraints /*: int */ = iConstraints;
   
   /*
    * Create a pointer to this object.
    */
   var oThis = this;
   
   /*
    * Create a temporary function named fnTemp.
    */
   var fnTemp = function () {
   
       /*
        * Create a dragstart event and fire it.
        */
       var oDragStartEvent = new zDragDropEvent();
       oDragStartEvent.initDragDropEvent("dragstart", true);
       
       /*
        * If the event isn"t cancelled, proceed.
        */
       if (oThis.dispatchEvent(oDragStartEvent)) {
           /*
            * Get the event objects, which is either the first
            * argument (for DOM-compliant browsers and Netscape 4.x)
            * or window.event (for IE).
            */    
           var oEvent = arguments[0] || window.event;
       
           /*
            * Get the difference between the clientX and clientY
            * and the position of the element.
            */
           oThis.diffX = oEvent.clientX - oThis.element.offsetLeft;
           oThis.diffY = oEvent.clientY - oThis.element.offsetTop;  
           /*
            * Add all DOM event handlers
            */
           oThis.attachEventHandlers();        
       
           /*
            * Set the currently dragged item.
            */
           zDrag.setCurrent(oThis);        
       }  
   };
   
   /*
    * Determine which method to use to add the event handler.
    */
   if (this.element.addEventListener) {
       this.element.addEventListener("mousedown", fnTemp, false);
   } else if (this.element.attachEvent) {
       this.element.attachEvent("onmousedown", fnTemp);
   } else {
       throw new Error("zDrag not supported in this browser.");
   }

}; /**

* Attaches event handlers for the mousemove and mouseup events.
* @scope private
* @private
* @type void
*/

zDraggable.prototype.attachEventHandlers = function () {

   /*
    * Create a pointer to this object.
    */
   var oThis = this;
   
   /*
    * Create a temporary function named tempMouseMove.
    */
   this.tempMouseMove = function () {
   
       /*
        * Get the event objects, which is either the first
        * argument (for DOM-compliant browsers and Netscape 4.x)
        * or window.event (for IE).
        */
       var oEvent = arguments[0] || window.event;
       
       /*
        * Get the new x and y coordinates for the dragged element by
        * subtracting the difference in the x and y direction from 
        * the mouse position on the screen (clientX and clientY).
        */
       var iNewX = oEvent.clientX - oThis.diffX;
       var iNewY = oEvent.clientY - oThis.diffY;
       
       /*
        * Move the x coordinate if zDraggable.DRAG_X is an option.
        */
       if (oThis.constraints & zDraggable.DRAG_X) {
           oThis.element.style.left = iNewX + "px";
       }
       
       /*
        * Move the y coordinate if zDraggable.DRAG_Y is an option.
        */
       if (oThis.constraints & zDraggable.DRAG_Y) {
           oThis.element.style.top = iNewY + "px";
       }
       
       /*
        * Create and fire a drag event.
        */
       var oDragEvent = new zDragDropEvent();
       oDragEvent.initDragDropEvent("drag", false);
       oThis.dispatchEvent(oDragEvent);
   };
   
   /*
    * Create a temporary function for the mouseup event.
    */
   oThis.tempMouseUp = function () {   
   
       /*
        * Get the event object.
        */
       var oEvent = arguments[0] || window.event;
       
       /*
        * Determine if the mouse is over a drop target.
        */
       var oDropTarget = oThis.getDropTarget(oEvent.clientX, oEvent.clientY);
       if (oDropTarget != null) {
       
           /*
            * Fire the drop event.
            */
           var oDropEvent = new zDragDropEvent();
           oDropEvent.initDragDropEvent("drop", false, oThis);
           oDropTarget.dispatchEvent(oDropEvent);
       }    
       /*
        * Create and fire a dragend event.
        */
       var oDragEndEvent = new zDragDropEvent();
       oDragEndEvent.initDragDropEvent("dragend", false);
       oThis.dispatchEvent(oDragEndEvent);
           
       /*
        * Clear the currently dragged item.
        */ 
       zDrag.clearCurrent();
               
       /*
        * Detach all of the event handlers.
        */
       oThis.detachEventHandlers();
   };
   
   /*
    * Determine which method to use to add the event handlers for
    * the mousemove and mouseup events.
    */
   if (document.addEventListener) {
       document.addEventListener("mousemove", this.tempMouseMove, false);
       document.addEventListener("mouseup", this.tempMouseUp, false);
   } else if (document.body.attachEvent) {
       document.body.attachEvent("onmousemove", this.tempMouseMove);
       document.body.attachEvent("onmouseup", this.tempMouseUp);
   } else {
       throw new Error("zDrag doesn"t support this browser.");
   }
   

}; /**

* Detaches event handlers for the mousemove and mouseup events.
* @scope private
*/

zDraggable.prototype.detachEventHandlers = function () {

   /*
    * Determine the method for removing the event handlers for the
    * mousemove and mouseup events.
    */
   if (document.removeEventListener) {
       document.removeEventListener("mousemove", this.tempMouseMove, false);
       document.removeEventListener("mouseup", this.tempMouseUp, false);
   } else if (document.body.detachEvent) {
       document.body.detachEvent("onmousemove", this.tempMouseMove);
       document.body.detachEvent("onmouseup", this.tempMouseUp);
   } else {
       throw new Error("zDrag doesn"t support this browser.");
   }

}; /**

* Determines the drop target that the mouse is over.
* @scope private
* @param iX The x-coordinate of the mouse.
* @param iY The y-coordinate of the mouse.
* @return The drop target if the mouse is over one, null otherwise.
*/

zDraggable.prototype.getDropTarget = function (iX /*: int */,

                                              iY /*: int */) /*: zDropTarget */ {
   for (var i=0; i < this.targets.length; i++) {
       if (this.targets[i].isOver(iX, iY)) {
           return this.targets[i];
       }
   }
   
   return null;

}; /**

* Moves the draggable element to a given position.
* @scope public
* @param iX The x-coordinate to move to.
* @param iY The y-coordinate to move to.
*/

zDraggable.prototype.moveTo = function (iX /*: int */, iY /*: int */) {

   this.element.style.left = iX + "px";
   this.element.style.top = iY + "px";

}; /**

* Returns the left coordinate of the element.
* @scope public
* @return The left coordinate of the element.
*/

zDraggable.prototype.getLeft = function () /*: int */ {

   return this.element.offsetLeft;

}; /**

* Returns the top coordinate of the element.
* @scope public
* @return The top coordinate of the element.
*/

zDraggable.prototype.getTop = function () /*: int */ {

   return this.element.offsetTop;

}; /**

* Encapsulates information about a drag drop event.
* @class
* @scope public
* @extends zEvent
*/

function zDragDropEvent() {

   /*
    * Inherit properties from zEvent.
    */
   zEvent.call(this);

} /*

* Inherit methods from zEvent.
*/

zDragDropEvent.prototype = new zEvent(); /**

* Initializes the event object with information for the event.
* @scope public
* @param sType The type of event encapsulated by the object.
* @param bCancelable True if the event can be cancelled.
* @param oRelatedTarget The alternate target related to the event.
*/

zDragDropEvent.prototype.initDragDropEvent = function(sType /*: String */,

                                                     bCancelable /*: boolean */,
                                                     oRelatedTarget /*: zEventTarget */) {
   /*
    * Call inherited method initEvent().
    */
   this.initEvent(sType, bCancelable);
   
   /*
    * Assign related target (may be null).
    */
   this.relatedTarget = oRelatedTarget;

} /**

* A target for a zDraggable to be dropped.
* @scope public
* @class
* @extends zEventTarget
*/

function zDropTarget(oElement) {

   /*
    * Inherit properties from zEventTarget.
    */
   zEventTarget.call(this);
   /*
    * Call constructor.
    */
   this.construct(oElement);

} /*

* Inherit methods from zEventTarget.
*/

zDropTarget.prototype = new zEventTarget; /**

* Creates a new instance based on the given DOM element.
* @constructor
* @scope public
* @param oElement The DOM element to make into a drop target.
*/

zDropTarget.prototype.construct = function (oElement /*: HTMLElement */) {

   /**
    * The DOM element to use as a drop target.
    * @scope private
    */
   this.element = oElement;
   

}; /**

* Determines if a given set of coordinates is over the element.
* @scope protected
* @param iX The x-coordinate to check.
* @param iY The y-coordinate to check.
* @return True if the coordinates are over the element, false if not.
*/

zDropTarget.prototype.isOver = function (iX /*: int */, iY /*: int */) /*: boolean */ {

   var iX1 = this.element.offsetLeft;
   var iX2 = iX1 + this.element.offsetWidth;
   var iY1 = this.element.offsetTop;
   var iY2 = iY1 + this.element.offsetHeight;
   return (iX >= iX1 && iX <= iX2 && iY >= iY1 && iY <= iY2);

}; /**

* Returns the left coordinate of the drop target.
* @scope public
* @return The left coordinate of the drop target.
*/

zDropTarget.prototype.getLeft = function () /*: int */ {

   return this.element.offsetLeft;

}; /**

* Returns the top coordinate of the drop target.
* @scope public
* @return The top coordinate of the drop target.
*/

zDropTarget.prototype.getTop = function () /*: int */{

   return this.element.offsetTop;

}; /**

* Returns the height of the drop target.
* @scope public
* @return The height of the drop target.
*/

zDropTarget.prototype.getHeight = function () /*: int */{

   return this.element.offsetHeight;

}; /**

* Returns the width of the drop target.
* @scope public
* @return The width of the drop target.
*/

zDropTarget.prototype.getWidth = function () /*: int */{

   return this.element.offsetWidth;

};

       </script>
       <script type="text/javascript">

           function doLoad() {
               var oDraggable = new zDraggable(document.getElementById("div1"), zDraggable.DRAG_X | zDraggable.DRAG_Y);
               var oDropTarget = new zDropTarget(document.getElementById("divDropTarget"));
               oDraggable.addDropTarget(oDropTarget);
               oDropTarget.addEventListener("drop", function (oEvent) { 
                   oEvent.relatedTarget.moveTo(oDropTarget.getLeft(), oDropTarget.getTop());
               });
           }
           
       </script>
       <style type="text/css">
           #div1 {
               background-color: red;
               height: 100px;
               width: 100px;
               position: absolute;
               z-index: 10;
           }
           
           #divDropTarget {
               background-color: blue;
               height: 200px;
               width: 200px;
               position: absolute;
               left: 300px;                
           }
       </style>
   </head>
   <body onload="doLoad()">

Try dragging the red square onto the blue square.

   </body>

</html></source>


System Drag And Drop between two text boxes

   <source lang="javascript">

<html>

   <head>
       <title>System Drag And Drop between two text boxes</title>
       <script type="text/javascript">
           function handleDragDropEvent(oEvent) {
               var oTextbox = document.getElementById("txt1");
               oTextbox.value +=  oEvent.type + "\n";
           }
       </script>
   </head>
   <body>

Try dragging the text from the left textbox to the right one.

<input type="text" value="drag this text" ondragstart="handleDragDropEvent(event)" ondrag="handleDragDropEvent(event)" ondragend="handleDragDropEvent(event)" /> <input type="text" ondragenter="handleDragDropEvent(event)" ondragover="handleDragDropEvent(event)" ondragleave="handleDragDropEvent(event)" ondrop="handleDragDropEvent(event)" />

<textarea rows="10" cols="25" readonly="readonly" id="txt1"></textarea>

   </body>

</html></source>