SiteExperts.com Logo Home | Community | Developer's Paradise | Jobs
User Groups | Site Tools | Site Information | Search

Inside Technique : Adding Drag and Drop : The Code

Below is the code that provides the drag-drop behavior. This code needs to be included within the page that uses the drag-drop attributes (or referenced as an external library).


/* The drag-drop framework is copyright 1997-98 insideDHTML.com, LLC.
   This code can be reused as long as this entire comment is not removed.
   For more information, see www.insideDHTML.com */

      var elDragged = null  // Track drag-source in global variable.

      // Note: All variables with "_" are private members added to the object
      // to cache calculated values.

      function testOver(iLeft, iTop) {
        // Test if the element is over a valid drop-target
        var hit = false
        if (elDragged.getAttribute("dropTarget")!=null) {
          // Test all potential targets
          for (var intLoop=0; intLoop el._top) && (iLeft > el._left) && (iLeft+elDragged.offsetWidth < el.offsetWidth+el._left) && (elDragged.offsetHeight+iTop < el.offsetHeight+el._top)) {
                  // Over target
                  elDragged.overTarget= el
                  var hit=true
                  elDragged._over[intLoop] = true
                  // Fire events when over
                  if (event.type=="mouseup") {
                    if (el.getAttribute("onDropTarget")!=null)
                       eval(el.getAttribute("onDropTarget"));
                  } else
                  {
                    if (el.getAttribute("onOverTarget")!=null) 
                      eval(el.getAttribute("onOverTarget"))
                  }
                }
              else {
                // Fire event when leaving
                if ((el.getAttribute("onOutTarget")!=null) && (elDragged._over[intLoop])) {
                    // User was just over a drop-target
                    elDragged.overTarget= el
                    eval(el.getAttribute("onOutTarget"))
                }
                elDragged._over[intLoop] = false
              }
            }
          }
        }
        return hit;
      }

      function doMouseUp() {
        if (elDragged!=null) 
          if (testOver(elDragged._left, elDragged._top)) {
            // Fire event on drag-source if dropped on target
            if (elDragged.getAttribute("onTarget"))
              eval(elDragged.getAttribute("onTarget"))
          }
          else
            if (elDragged.getAttribute("onNoTarget"))
              eval(elDragged.getAttribute("onNoTarget"))
        // Reset global variable
        elDragged=null
      }

      function doMouseMove() {
        // Check if mouse button is down and if an element is being dragged
        if ((1 == event.button) && (elDragged != null)) {
          // Set new position
          var intTop = event.clientY+document.body.scrollTop; 
          var intLeft = event.clientX + document.body.scrollLeft;
          elDragged.style.pixelTop = intTop  - elDragged._lessTop - elDragged.y;
          elDragged.style.pixelLeft = intLeft - elDragged._lessLeft - elDragged.x;
          // Cache updated info
          elDragged._left = elDragged._lessLeft + elDragged.offsetLeft + document.body.scrollLeft
          elDragged._top = elDragged.offsetTop+ elDragged._lessTop +document.body.scrollTop
          // Test if over target
          testOver(elDragged._left, elDragged._top)
          event.returnValue = false;
        };
      };

      function checkDrag(elCheck) {
        // Check if the clicked inside an element that supports dragging
        // This allows rich HTML in drag-source
        while (elCheck!=null) {
          if (null!=elCheck.getAttribute("dragEnabled")) 
            return elCheck
          elCheck = elCheck.parentElement
        }      
        return null
      }

      function doMouseDown() {
        // On the mouse down, test if element can be dragged

        var elCurrent = checkDrag(event.srcElement)
        // For draggable elements, cache all calculations up front. This is for performance.
        if (null!=elCurrent) {
            elDragged = elCurrent;
            // Determine where the mouse is in the element
            elDragged.x = event.offsetX
            elDragged.y = event.offsetY

            // Make sure we are using pixel units everywhere
            elDragged.style.top = elDragged.offsetTop + "px"
            elDragged.style.left = elDragged.offsetLeft + "px"

            // Calculate real position from upper-left of document.
            var op = event.srcElement
            // Find real location in respect to element being dragged.
            if ((elDragged!=op.offsetParent) && (elDragged!=event.srcElement)) {
              while (op!=elDragged) {
                elDragged.x+=op.offsetLeft
                elDragged.y+=op.offsetTop
                op=op.offsetParent
              }
            }

          // Move the element
          // Where the mouse is in the document
          // Calculate what element the mouse is really in
          var intLessTop  = 0; var intLessLeft = 0;
          var elCurrent = elDragged.offsetParent;
          while (elCurrent.offsetParent!=null) {
            intLessTop+=elCurrent.offsetTop;
            intLessLeft+=elCurrent.offsetLeft;
            elCurrent = elCurrent.offsetParent;
          }
          elDragged._lessTop = intLessTop
          elDragged._lessLeft = intLessLeft
          // Calculate and cache target information
          if (null!=elDragged.getAttribute("dropTarget")) { 
            elDragged._targets = elDragged.getAttribute("dropTarget").split(",")
            elDragged._over = new Array
            elDragged._elTargets = new Array
            for (var intLoop=0; intLoop < elDragged._targets.length; intLoop++) {
              var el = document.all[elDragged._targets[intLoop]]
              if (null!=el) {
                elDragged._elTargets[intLoop]= el;
                var intLessTop  = el.offsetTop; var intLessLeft = el.offsetLeft;
                var elCurrent = el.offsetParent;
                var intTop = document.body.scrollTop; 
                var intLeft =  document.body.scrollLeft;
                while (elCurrent.offsetParent!=null) {
                  intLessTop+=elCurrent.offsetTop;
                  intLessLeft+=elCurrent.offsetLeft;
                  elCurrent = elCurrent.offsetParent;
                }
                el._top = intLessTop  + intTop
                el._left = intLessLeft + intLeft
              }
            }
          }
        }
      }

      function doDragTest() {
        // Don't start text selections in dragged elements.
        return (null==checkDrag(event.srcElement) && (elDragged==null))
      }

      // Process all mouse events.
      document.onmousedown = doMouseDown;
      document.onmousemove = doMouseMove;
      document.onmouseup = doMouseUp;
      document.ondragstart = doDragTest
      document.onselectstart = doDragTest;

    
Discuss and Rate this Article