一个拖拽例子

<STYLE>LI {
 MARGIN-BOTTOM: 10px
}
OL {
 MARGIN-TOP: 5px
}
.DragContainer {
 BORDER-RIGHT: #669999 2px solid; PADDING-RIGHT: 5px; BORDER-TOP: #669999 2px solid; PADDING-LEFT: 5px; FLOAT: left; PADDING-BOTTOM: 0px; MARGIN: 3px; BORDER-LEFT: #669999 2px solid; WIDTH: 100px; PADDING-TOP: 5px; BORDER-BOTTOM: #669999 2px solid
}
.OverDragContainer {
 BORDER-RIGHT: #669999 2px solid; PADDING-RIGHT: 5px; BORDER-TOP: #669999 2px solid; PADDING-LEFT: 5px; FLOAT: left; PADDING-BOTTOM: 0px; MARGIN: 3px; BORDER-LEFT: #669999 2px solid; WIDTH: 100px; PADDING-TOP: 5px; BORDER-BOTTOM: #669999 2px solid
}
.OverDragContainer {
 BACKGROUND-COLOR: #eee
}
.DragBox {
 BORDER-RIGHT: #000 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #000 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 10px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 2px; BORDER-LEFT: #000 1px solid; WIDTH: 94px; CURSOR: pointer; PADDING-TOP: 2px; BORDER-BOTTOM: #000 1px solid; FONT-FAMILY: verdana, tahoma, arial; BACKGROUND-COLOR: #eee
}
.OverDragBox {
 BORDER-RIGHT: #000 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #000 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 10px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 2px; BORDER-LEFT: #000 1px solid; WIDTH: 94px; CURSOR: pointer; PADDING-TOP: 2px; BORDER-BOTTOM: #000 1px solid; FONT-FAMILY: verdana, tahoma, arial; BACKGROUND-COLOR: #eee
}
.DragDragBox {
 BORDER-RIGHT: #000 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #000 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 10px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 2px; BORDER-LEFT: #000 1px solid; WIDTH: 94px; CURSOR: pointer; PADDING-TOP: 2px; BORDER-BOTTOM: #000 1px solid; FONT-FAMILY: verdana, tahoma, arial; BACKGROUND-COLOR: #eee
}
.miniDragBox {
 BORDER-RIGHT: #000 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #000 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 10px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 2px; BORDER-LEFT: #000 1px solid; WIDTH: 94px; CURSOR: pointer; PADDING-TOP: 2px; BORDER-BOTTOM: #000 1px solid; FONT-FAMILY: verdana, tahoma, arial; BACKGROUND-COLOR: #eee
}
.OverDragBox {
 BACKGROUND-COLOR: #ffff99
}
.DragDragBox {
 BACKGROUND-COLOR: #ffff99
}
.DragDragBox {
 FILTER: alpha(opacity=50); BACKGROUND-COLOR: #ff99cc
}
LEGEND {
 FONT-WEIGHT: bold; FONT-SIZE: 12px; COLOR: #666699; FONT-FAMILY: verdana, tahoma, arial
}
FIELDSET {
 PADDING-RIGHT: 3px; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; PADDING-TOP: 3px
}
.History {
 FONT-SIZE: 10px; OVERFLOW: auto; WIDTH: 100%; FONT-FAMILY: verdana, tahoma, arial; HEIGHT: 82px
}
#DragContainer8 {
 BORDER-RIGHT: #669999 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: #669999 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 0px; BORDER-LEFT: #669999 1px solid; WIDTH: 110px; PADDING-TOP: 5px; BORDER-BOTTOM: #669999 1px solid; HEIGHT: 110px
}
.miniDragBox {
 FLOAT: left; MARGIN: 0px 5px 5px 0px; WIDTH: 20px; HEIGHT: 20px
}
pre{border:1 solid #CCC;background-color:#F8F8F0;padding:10px;}
</STYLE>


<script>

// iMouseDown represents the current mouse button state: up or down
// imousedown 代表了当前鼠标按键状态:向上或向下
/*
lMouseState represents the previous mouse button state so that we can
check for button clicks and button releases:

if(iMouseDown && !lMouseState) // button just clicked!
if(!iMouseDown && lMouseState) // button just released!

lmousestate代表了以往鼠标按键状态,使我们可以
检查按钮,点击按钮发布:

如果( imousedown & & ! lmousestate ) / /按钮刚刚点击!
如果( ! imousedown & & lmousestate ) / /按钮刚刚公布!
*/
var mouseOffset = null;
var iMouseDown  = false;
var lMouseState = false;
var dragObject  = null;

// Demo 0 variables   演示0变数
var DragDrops   = [];
var curTarget   = null;
var lastTarget  = null;
var dragHelper  = null;
var tempDiv     = null;
var rootParent  = null;
var rootSibling = null;

//为Number增加一个属性,判断当前数据类型是否是数字
Number.prototype.NaN0=function(){return isNaN(this)?0:this;}

function CreateDragContainer(){
 /*
 Create a new "Container Instance" so that items from one "Set" can not
 be dragged into items from another "Set"
 创建一个新的"集装箱例如" ,使项目从一"设置" ,是不能被拖进项目,从另外一个"集"
 */
 var cDrag        = DragDrops.length;
 DragDrops[cDrag] = [];

 /*
 Each item passed to this function should be a "container".  Store each
 of these items in our current container
 每个项目通过这项功能应该是一个"集装箱" 。每个店这些项目在我们目前的货柜
 */
 for(var i=0; i<arguments.length; i++){
  var cObj = arguments[i];
  DragDrops[cDrag].push(cObj);
  cObj.setAttribute('DropObj', cDrag);

  /*
  Every top level item in these containers should be draggable.  Do this
  by setting the DragObj attribute on each item and then later checking
  this attribute in the mouseMove function
  每一个高层项目,在这些容器应拖放。这样做通过设置dragobj属性,对每个项目的,后来检查这个属性在mousemove功能
  */
  for(var j=0; j<cObj.childNodes.length; j++){

   // Firefox puts in lots of #text nodes...skip these    火狐了,在大量的#文本节点...跳过这些
   if(cObj.childNodes[j].nodeName=='#text') continue;

   cObj.childNodes[j].setAttribute('DragObj', cDrag);
  }
 }
}

//获得发生事件鼠标的位置----------------------对象2
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
 };
}

//获得鼠标的偏移量(对象2-对象1)
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};
}


//获得事件发生的实际位置----------------------对象1
function getPosition(e){
 var left = 0;
 var top  = 0;
 
 //相对位置累加得到实际位置
 while (e.offsetParent)
 {
  left += e.offsetLeft + (e.currentStyle?(parseInt(e.currentStyle.borderLeftWidth)).NaN0():0);
  top  += e.offsetTop  + (e.currentStyle?(parseInt(e.currentStyle.borderTopWidth)).NaN0():0);
  e     = e.offsetParent;
 }
 left += e.offsetLeft + (e.currentStyle?(parseInt(e.currentStyle.borderLeftWidth)).NaN0():0);
 top  += e.offsetTop  + (e.currentStyle?(parseInt(e.currentStyle.borderTopWidth)).NaN0():0);
 return {x:left, y:top};
}

//鼠标移动
function mouseMove(ev){
 ev         = ev || window.event;

 /*
 We are setting target to whatever item the mouse is currently on

 Firefox uses event.target here, MSIE uses event.srcElement

 我们设定的目标,不管项目老鼠是目前对火狐用途event.target这里,选用800 x600 。 MSIE用途event.srcelement
 */
 var target   = ev.target || ev.srcElement;
 var mousePos = mouseCoords(ev);

 // mouseOut event - fires if the item the mouse is on has changed    mouseout事件-火灾,如果该项目老鼠是对已改变
 if(lastTarget && (target!==lastTarget)){
  // reset the classname for the target element      复位) className为目标元素
  var origClass = lastTarget.getAttribute('origClass');
  if(origClass) lastTarget.className = origClass;
 }

 /*
 dragObj is the grouping our item is in (set from the createDragContainer function).
 if the item is not in a grouping we ignore it since it can't be dragged with this
 script.
 dragobj是分组,我们项目是在(一套从createdragcontainer功能) 。 如果这个项目是不是在一个分组,我们不理它,因为它不能被拖进这个脚本。
 */
 var dragObj = target.getAttribute('DragObj');

  // if the mouse was moved over an element that is draggable    即使鼠标提出了一个多因素,即拖放
 if(dragObj!=null){

  // mouseOver event - Change the item's class if necessary   mouseover事件-改变项目的阶级,如果有必要
  if(target!=lastTarget){
   var oClass = target.getAttribute('overClass');
   if(oClass){
    target.setAttribute('origClass', target.className);
    target.className = oClass;
   }
  }

  // if the user is just starting to drag the element   如果用户刚开始拖曳元
  if(iMouseDown && !lMouseState){
   // mouseDown target     mousedown目标
   curTarget     = target;

   // Record the mouse x and y offset for the element     记录鼠标X和Y抵销该元素
   rootParent    = curTarget.parentNode;
   rootSibling   = curTarget.nextSibling;

   mouseOffset   = getMouseOffset(target, ev);

   // We remove anything that is in our dragHelper DIV so we can put a new item in it.    我们删除任何东西,这就是我们的draghelper理学系因此,我们可以把一个新项目。
   for(var i=0; i<dragHelper.childNodes.length; i++) dragHelper.removeChild(dragHelper.childNodes[i]);

   // Make a copy of the current item and put it in our drag helper.   令的副本,目前的项目,并把它放在我们的拖累帮手。
   dragHelper.appendChild(curTarget.cloneNode(true));
   dragHelper.style.display = 'block';

   // set the class on our helper DIV if necessary   定阶层对我们的帮手理学系,如果有必要
   var dragClass = curTarget.getAttribute('dragClass');
   if(dragClass){
    dragHelper.firstChild.className = dragClass;
   }

   // disable dragging from our helper DIV (it's already being dragged)   禁用拖从我们的帮手理学系(它已经被拖入)
   dragHelper.firstChild.removeAttribute('DragObj');

   /*
   Record the current position of all drag/drop targets related
   to the element.  We do this here so that we do not have to do
   it on the general mouse move event which fires when the mouse
   moves even 1 pixel.  If we don't do this here the script
   would run much slower.

   记录当前位置的所有拖曳/落指标相关到元素。我们这样做是在这里,让我们不必事必躬亲这对一般鼠标移动事件,其中火灾时,该鼠标动作,甚至1个像素。如果我们不这样做此剧本会运行缓慢得多。
   */
   var dragConts = DragDrops[dragObj];

   /*
   first record the width/height of our drag item.  Then hide it since
   it is going to (potentially) be moved out of its parent.
   第一纪录的宽度/高度我们拖曳项目。然后把它隐藏自这是去(可能)被迁出的,其母公司。
   */
   curTarget.setAttribute('startWidth',  parseInt(curTarget.offsetWidth));
   curTarget.setAttribute('startHeight', parseInt(curTarget.offsetHeight));
   curTarget.style.display  = 'none';

   // loop through each possible drop container   回路通过每个可能下降货柜
   for(var i=0; i<dragConts.length; i++){
    with(dragConts[i]){
     var pos = getPosition(dragConts[i]);

     /*
     save the width, height and position of each container.

     Even though we are saving the width and height of each
     container back to the container this is much faster because
     we are saving the number and do not have to run through
     any calculations again.  Also, offsetHeight and offsetWidth
     are both fairly slow.  You would never normally notice any
     performance hit from these two functions but our code is
     going to be running hundreds of times each second so every
     little bit helps!

     Note that the biggest performance gain here, by far, comes
     from not having to run through the getPosition function
     hundreds of times.

     拯救宽度,高度和位置,每个货柜。
     即使我们是节约的宽度和高度的相互
     集装箱返回集装箱,这是快得多,因为
     我们节省多少不具备贯穿
     任何计算。此外,的offsetParent和offsetwidth
     都是比较慢。你绝不会通常任何通知
     性能达到这两个功能,但我们的代码
     去运行数百次,每一秒钟,让每
     有点帮助!

     注说,最大的性能增益在这里,到目前为止,来
     从不用贯穿getposition功能
     数百人次。
     */
     setAttribute('startWidth',  parseInt(offsetWidth));
     setAttribute('startHeight', parseInt(offsetHeight));
     setAttribute('startLeft',   pos.x);
     setAttribute('startTop',    pos.y);
    }

    // loop through each child element of each container   回路通过每个孩子的要素,每个货柜
    for(var j=0; j<dragConts[i].childNodes.length; j++){
     with(dragConts[i].childNodes[j]){
      if((nodeName=='#text') || (dragConts[i].childNodes[j]==curTarget)) continue;

      var pos = getPosition(dragConts[i].childNodes[j]);

      // save the width, height and position of each element  拯救宽度,高度和位置,每个元素
      setAttribute('startWidth',  parseInt(offsetWidth));
      setAttribute('startHeight', parseInt(offsetHeight));
      setAttribute('startLeft',   pos.x);
      setAttribute('startTop',    pos.y);
     }
    }
   }
  }
 }

 // If we get in here we are dragging something   如果我们在这里,我们是拖东西
 if(curTarget){
  // move our helper div to wherever the mouse is (adjusted by mouseOffset)   打动帮手理学系,哪里是鼠标(调整后,由mouseoffset )
  dragHelper.style.top  = mousePos.y - mouseOffset.y;
  dragHelper.style.left = mousePos.x - mouseOffset.x;

  var dragConts  = DragDrops[curTarget.getAttribute('DragObj')];
  var activeCont = null;

  var xPos = mousePos.x - mouseOffset.x + (parseInt(curTarget.getAttribute('startWidth')) /2);
  var yPos = mousePos.y - mouseOffset.y + (parseInt(curTarget.getAttribute('startHeight'))/2);

  // check each drop container to see if our target object is "inside" the container  又相互制约的辍学货柜看到,如果我们的目标对象是"对内"货柜
  for(var i=0; i<dragConts.length; i++){
   with(dragConts[i]){
    if(((getAttribute('startLeft'))                               < xPos) &&
     ((getAttribute('startTop'))                                < yPos) &&
     ((getAttribute('startLeft') + getAttribute('startWidth'))  > xPos) &&
     ((getAttribute('startTop')  + getAttribute('startHeight')) > yPos)){

      /*
      our target is inside of our container so save the container into
      the activeCont variable and then exit the loop since we no longer
      need to check the rest of the containers

      我们的目标是在里面,香港的货柜以便节省货柜成
      该activecont变量,然后退出循环,因为我们已不再
      要查证其余的集装箱
      */
      activeCont = dragConts[i];

      // exit the for loop    退出for循环
      break;
    }
   }
  }

  // Our target object is in one of our containers.  Check to see where our div belongs   我们的目标对象是,在我们的一个容器。检查一下我们的广告属于
  if(activeCont){
   // beforeNode will hold the first node AFTER where our div belongs   beforenode将举行第一次结后,我们的广告属于
   var beforeNode = null;

   // loop through each child node (skipping text nodes).   回路通过每个孩子节点(跳跃文本节点) 。
   for(var i=activeCont.childNodes.length-1; i>=0; i--){
    with(activeCont.childNodes[i]){
     if(nodeName=='#text') continue;

     // if the current item is "After" the item being dragged   如果目前的一个项目是"后, "该项目被拖入
     if(
      curTarget != activeCont.childNodes[i]                              &&
      ((getAttribute('startLeft') + getAttribute('startWidth'))  > xPos) &&
      ((getAttribute('startTop')  + getAttribute('startHeight')) > yPos)){
       beforeNode = activeCont.childNodes[i];
     }
    }
   }

   // the item being dragged belongs before another item   该项目被拖入之前属于另一个项目
   if(beforeNode){
    if(beforeNode!=curTarget.nextSibling){
     activeCont.insertBefore(curTarget, beforeNode);
    }

   // the item being dragged belongs at the end of the current container   该项目被拖入属于在结束目前的集装箱
   } else {
    if((curTarget.nextSibling) || (curTarget.parentNode!=activeCont)){
     activeCont.appendChild(curTarget);
    }
   }

   // make our drag item visible    使我们的拖曳项目有形
   if(curTarget.style.display!=''){
    curTarget.style.display  = '';
   }
  } else {

   // our drag item is not in a container, so hide it.    我们拖动项目,是不是在一个货柜内,所以把它隐藏。
   if(curTarget.style.display!='none'){
    curTarget.style.display  = 'none';
   }
  }
 }

 // track the current mouse state so we can compare against it next time   田径目前的鼠标状态,所以我们可以比较反对下一次
 lMouseState = iMouseDown;

 // mouseMove target   mousemove目标
 lastTarget  = target;

 // track the current mouse state so we can compare against it next time    田径目前的鼠标状态,所以我们可以比较反对下一次
 lMouseState = iMouseDown;

 // this helps prevent items on the page from being highlighted while dragging   这有助于防止项目上的一页,从突出,而拖
 return false;
}

function mouseUp(ev){
 if(curTarget){
  // hide our helper object - it is no longer needed   隐藏我们的帮手对象-它不再需要
  dragHelper.style.display = 'none';

  // if the drag item is invisible put it back where it was before moving it   如果拖动项目是无形的把它回到它之前移动它
  if(curTarget.style.display == 'none'){
   if(rootSibling){
    rootParent.insertBefore(curTarget, rootSibling);
   } else {
    rootParent.appendChild(curTarget);
   }
  }

  // make sure the drag item is visible    确保拖动项目是有形
  curTarget.style.display = '';
 }
 curTarget  = null;
 iMouseDown = false;
}

function mouseDown(){
 iMouseDown = true;
 if(lastTarget){
  return false;
 }
}

document.onmousemove = mouseMove;
document.onmousedown = mouseDown;
document.onmouseup   = mouseUp;

window.onload = function(){
 // Create our helper object that will show the item while dragging    创造我们的帮手对象将会呈现出项目,而拖
 dragHelper = document.createElement('DIV');
 dragHelper.style.cssText = 'position:absolute;display:none;';
  
 CreateDragContainer(
  document.getElementById('DragContainer1'),
  document.getElementById('DragContainer2'),
  document.getElementById('DragContainer3')
 );

 document.body.appendChild(dragHelper);
}

</script>

<!--the mouse over and dragging class are defined on each item   鼠标拖进阶层的定义是对每个项目-->

<div class="DragContainer" id="DragContainer1">
 <div class="DragBox" id="Item1"  overClass="OverDragBox" dragClass="DragDragBox">Item #1</div>
 <div class="DragBox" id="Item2"  overClass="OverDragBox" dragClass="DragDragBox">Item #2</div>
 <div class="DragBox" id="Item3"  overClass="OverDragBox" dragClass="DragDragBox">Item #3</div>
 <div class="DragBox" id="Item4"  overClass="OverDragBox" dragClass="DragDragBox">Item #4</div>
</div>
<div class="DragContainer" id="DragContainer2">
 <div class="DragBox" id="Item5"  overClass="OverDragBox" dragClass="DragDragBox">Item #5</div>
 <div class="DragBox" id="Item6"  overClass="OverDragBox" dragClass="DragDragBox">Item #6</div>
 <div class="DragBox" id="Item7"  overClass="OverDragBox" dragClass="DragDragBox">Item #7</div>
 <div class="DragBox" id="Item8"  overClass="OverDragBox" dragClass="DragDragBox">Item #8</div>
</div>
<div class="DragContainer" id="DragContainer3">
 <div class="DragBox" id="Item9"  overClass="OverDragBox" dragClass="DragDragBox">Item #9</div>
 <div class="DragBox" id="Item10" overClass="OverDragBox" dragClass="DragDragBox">Item #10</div>
 <div class="DragBox" id="Item11" overClass="OverDragBox" dragClass="DragDragBox">Item #11</div>
 <div class="DragBox" id="Item12" overClass="OverDragBox" dragClass="DragDragBox">Item #12</div>

前端小菜。。。
努力成为大菜!
原文地址:https://www.cnblogs.com/chengj/p/1990149.html