本文译自:http://www.webreference.com/programming/javascript/mk/column2/index.html
所有版权归原文所有
由sohotx.com雪山老人翻译整理,转载请标明javascript的特点是dom的处理与网页效果,大多数情况我们只用到了这个语言的最简单的功能,比如制作图片轮播/网页的tab等等,这篇文章将向你展示如何在自己的网页上制作拖拽.有很多理由让你的网站加入拖拽功能,最简单的一个是数据重组.例如:你有一个序列的内容让用户排序,用户需要给每个条目进行输入或者用select选择,替代前面这个方法的就是拖拽.或许你的网站也需要一个用户可以拖动的导航窗口!那么这些效果都是很简单:因为你可以很容易的实现!网页上实现拖拽其实也不是很复杂.第一你需要知道鼠标坐标,第二你需要知道用户鼠标点击一个网页元素并实现拖拽,最后我们要实现移动这个元素.样例- 拖拽页面元素
Item #1Item #2Item #3Item #4Item #5Item #6Item #7Item #8Item #9Item #10Item #11Item #12 
获取鼠标移动信息 第一我们需要获取鼠标的坐标.我们加一个用户函数到document.onmousemove就可以了:document.onmousemove = mouseMove;function mouseMove(ev){
 ev           = ev || window.event;
 var mousePos = mouseCoords(ev);
}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
 };
}Demo - Move your mouseMouse X Position:    Mouse Y Position:   实现上面的独立脚本,选取存下来,并把<>的全角换成半角,就可以看到效果!<script>function mouseMove(ev){
 ev           = ev || window.event;
 var mousePos = mouseCoords(ev);
  document.getElementById('xxx').value = mousePos.x;
  document.getElementById('yyy').value = mousePos.y;
}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
 };
}document.onmousemove = mouseMove;
</script>
<input id=xxx type=text>
<br>
<input id=yyy type=text>
你首先要声明一个evnet对象.不论何时你移动鼠标/点击/按键等等,会对应一个event的事件.在Internet Explorer里event是全局变量,会被存储在window.event里. 在firefox中,或者其他浏览器,event事件会被相应的自定义函数获取.当我们将mouseMove函数赋值于document.onmousemove,mouseMove会获取鼠标移动事件. (ev = ev || window.event) 这样让ev在所有浏览器下获取了event事件,在Firefox下"||window.event"将不起作用,因为ev已经有了赋值.在MSIE下ev是空的,所以ev将设置为window.event.因为我们在这篇文章中需要多次获取鼠标坐标,所以我们设计了mouseCoords这个函数,它只包含了一个参数,就是the event.我们需要运行在MSIE与Firefox为首的其他浏览器下.Firefox以event.pageX和event.pageY来代表鼠标相应于文档左上角的位置.如果你有一个500*500的窗口,而且你的鼠标在正中间,那么paegX和pageY将是250,当你将页面往下滚动500px,那么pageY将是750.此时pageX不变,还是250.MSIE和这个相反,MSIE将event.clientX与event.clientY来代表鼠标与ie窗口的位置,并不是文档.当我们有一个500*500的窗口,鼠标在正中间,那么clientX与clientY也是250,如果你垂直滚动窗口到任何位置,clientY仍然是250,因为相对ie窗口并没有变化.想得到正确的结果,我们必须加入scrollLeft与scrollTop这两个相对于文档鼠标位置的属性.最后,由于MSIE并没有0,0的文档起始位置,因为通常会设置2px的边框在周围,边框的宽度包含在document.body.clientLeft与clientTop这两个属性中,我们再加入这些到鼠标的位置中.很幸运,这样mouseCoords函数就完成了,我们不再为坐标的事操心了.捕捉鼠标点击
下次我们将知道鼠标何时点击与何时放开.如果我们跳过这一步,我们在做拖拽时将永远不知道鼠标移动上面时的动作,这将是恼人的与违反直觉的.这里有两个函数帮助我们:onmousedown与onmouseup.我们预先设置函数来接收document.onmousemove,这样看起来很象我们会获取document.onmousedown与document.onmouseup.但是当我们获取document.onmousedown时,我们同时获取了任何对象的点击属性如:text,images,tables等等.我们只想获取那些需要拖拽的属性,所以我们设置函数来获取我们需要移动的对象.Demo - Click any image 
 
You clicked on:   
实现上面的独立脚本,选取存下来,并把<>的全角换成半角,就可以看到效果!<script>
function mouseDown(ev){
 ev         = ev || window.event;
 var target = ev.target || ev.srcElement; if(target.onmousedown || target.getAttribute('DragObj')){
  return false;
 }
}function makeClickable(item){
 if(!item) return;
 item.onmousedown = function(ev){
  document.getElementById('ClickImage').value = this.name;
 }
}
document.onmousedown = mouseDown;
window.onload = function(){
 makeClickable(document.getElementById('ClickImage1'));
 makeClickable(document.getElementById('ClickImage2'));
 makeClickable(document.getElementById('ClickImage3'));
 makeClickable(document.getElementById('ClickImage4'));
}</script><FIELDSET id=Demo3>
<h3>
  Demo - Click any image
</h3>
<IMG id=ClickImage1 
src="http://www.webreference.com/programming/javascript/mk/column2/Dragging and Dropping in javascript_files/drag_drop_spade.gif" 
name=Spade><IMG id=ClickImage2 
src="http://www.webreference.com/programming/javascript/mk/column2/Dragging and Dropping in javascript_files/drag_drop_heart.gif" 
name=Heart><IMG id=ClickImage3 
src="http://www.webreference.com/programming/javascript/mk/column2/Dragging and Dropping in javascript_files/drag_drop_diamond.gif" 
name=Diamond><IMG id=ClickImage4 
src="http://www.webreference.com/programming/javascript/mk/column2/Dragging and Dropping in javascript_files/drag_drop_club.gif"
 name=Club> 
<BR>You clicked on: <INPUT id=ClickImage type="text"> </FIELDSET> 移动一个元素
我们知道了怎么捕捉鼠标移动与点击.剩下的就是移动元素了.首先,要确定一个明确的页面位置,css样式表要用'absolute'.设置元素绝对位置意味着我们可以用样式表的.top和.left来定位,可以用相对位置来定位了.我们将鼠标的移动全部相对页面top-left,基于这点,我们可以进行下一步了.当我们定义item.style.position='absolute',所有的操作都是改变left坐标与top坐标,然后它移动了.document.onmousemove = mouseMove;
document.onmouseup   = mouseUp;var dragObject  = null;
var mouseOffset = null;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};
}function getPosition(e){
 var left = 0;
 var top  = 0; while (e.offsetParent){
  left += e.offsetLeft;
  top  += e.offsetTop;
  e     = e.offsetParent;
 } left += e.offsetLeft;
 top  += e.offsetTop; return {x:left, y:top};
}function mouseMove(ev){
 ev           = ev || window.event;
 var mousePos = mouseCoords(ev); if(dragObject){
  dragObject.style.position = 'absolute';
  dragObject.style.top      = mousePos.y - mouseOffset.y;
  dragObject.style.left     = mousePos.x - mouseOffset.x;  return false;
 }
}
function mouseUp(){
 dragObject = null;
}function makeDraggable(item){
 if(!item) return;
 item.onmousedown = function(ev){
  dragObject  = this;
  mouseOffset = getMouseOffset(this, ev);
  return false;
 }
}Demo - Drag any of the images
  
实现上面效果的代码,注意将<>的全角换成半角<script>
var iMouseDown  = false;
var dragObject  = null;
var curTarget   = null;function makeDraggable(item){
 if(!item) return;
 item.onmousedown = function(ev){
  dragObject  = this;
  mouseOffset = getMouseOffset(this, ev);
  return false;
 }
}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};
}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 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
 };
}function mouseDown(ev){
 ev         = ev || window.event;
 var target = ev.target || ev.srcElement; if(target.onmousedown || target.getAttribute('DragObj')){
  return false;
 }
}function mouseUp(ev){ dragObject = null; iMouseDown = false;
}
function mouseMove(ev){
 ev         = ev || window.event; /*
该文章转载自德仔工作室:http://www.dezai.cn/Article_Show.asp?ArticleID=8704

解决方案 »

  1.   

    你这个问题在javascript高级程序设计里面有讲的。
      

  2.   

    事件对象在IE里和FIREFOX里表示不一样
    在IE里事件对象是window.event,是全局对象
    在FIREFOX里事件对象是通过函数参数注入的ev.target
    function mouseDown(ev){
    ev = ev  ¦ ¦ window.event;
    target = ev.srcElement  ¦ ¦ ev.target;}
    这段代码是实现IE和FIREFOX事件对象的通用访问