建站学 - 轻松建站从此开始!

建站学-个人建站指南,网页制作,网站设计,网站制作教程

javascript的拖放入门

时间:2009-09-09 15:38来源: 作者: 点击:
既然说是入门,本文给出的函数都尽可能短小,但不失强大,并兼容所有浏览器。要想拖动页面上的一个元素,说白了就是让它实现位移。CSS中最能体现这种思想的是绝对定位,因为绝对定位能使元素脱离原来的文档流,但原来的物理空间还保留着,这就不影响周围的元素了。接着

既然说是入门,本文给出的函数都尽可能短小,但不失强大,并兼容所有浏览器。要想拖动页面上的一个元素,说白了就是让它实现位移。CSS中最能体现这种思想的是绝对定位,因为绝对定位能使元素脱离原来的文档流,但原来的物理空间还保留着,这就不影响周围的元素了。接着下来就是设置事件侦听器,分别在mousedown,mousemove,mouseup绑定对应的回调函数,一旦触发这些事件,浏览器就会自动调用它们。我们分别把这些回调函数命名为dragstart,drag与dragend。

  • 在dragstart方法中,我们的工作取得鼠标相对于事件源的距离。IE中,我们可以很轻松地用offsetX与offsetY实现,在firefox中我们要用layerX与layerY。其他浏览器大多数是墙头草,两个都实现,但Opera是IE那一方的。为了实现全面兼容,就要绕点远路,利用e.clientX - el.offsetLeft与e.clientY - el.offsetTop获取它们。并在此方法中开始监听mousemove与mouseup事件。
  • 在drag方法,我们要将拖动的距离加到原来的top与left上,以实现位移。拖动过程,可能引发沿文本的被选中,我们需要清除文本。
  • 在dragend方法,我们要卸载绑定事件,释放内存。

为了共享方法,我们把它们都做成原型方法。

01.var Drag = function(id){
02.  this.node = document.getElementById(id);
03.  this.node.style.position = "absolute"
04.  this.node.me = this;//保存自身的引用
05.  this.node.onmousedown = this.dragstart;//监听mousedown事件
06.}
07.Drag.prototype = {
08.  constructor:Drag,
09.  dragstart:function(e){
10.    var e = e || window.event,//获得事件对象
11.    self = this.me,//获得拖动对象
12.    node = self.node;//获得拖动元素
13.    //鼠标光标相对于事件源对象的坐标
14.    node.offset_x = e.clientX - node.offsetLeft;
15.    node.offset_y = e.clientY - node.offsetTop;
16.    node.onmousemove = self.drag;//监听mousemove事件
17.    node.onmouseup = self.dragend;//监听mouseup事件
18.  },
19.  drag:function(e){
20.    var e = e || window.event,//获得事件对象
21.    self = this.me,//获得拖动对象
22.    node = self.node;//获得拖动元素
23.    node.style.cursor = "pointer";
24.    //将拖动的距离加再在原先的left与top上,以实现位移
25.    !+"\v1"? document.selection.empty() : window.getSelection().removeAllRanges();
26.    node.style.left = e.clientX - node.offset_x  + "px";
27.    node.style.top = e.clientY - node.offset_y  + "px";
28.    node.onmouseup = self.dragend;//监听mouseup事件
29.  },
30.  dragend:function(){
31.    var self = this.me,//获得拖动对象
32.    node = self.node;//获得拖动元素
33.    node.onmousemove = null;
34.    node.onmouseup = null;
35.  }
36.}

现在我们的类就可以运作了,但正如你们所看到的那样,当鼠标拖动太快会出现鼠标移出div的情况。这是因为移动得越快,位移的距离就越大,拖动元素一下子从我们的鼠标溜走了,就无法调用mouseup事件。在IE中我们可以利用setCapture()来补救,但一旦某个元素调用setCapture(),文档中所有后续的鼠标事件都会在冒泡之前传到该元素,直到调用了releaseCapture()。换言之,在完成这些鼠标事件之前,它是不执行其他事件,一直占着线程,于是出现了我们的光标离开拖动元素的上方也能拖动元素的怪异现象。

你在拖动块上点一下,然后再到拖动块外面点一下,就可以实现"隔空拖动"的神奇效果了!(当然只限IE)

由于鼠标事件一直接着线程,所以在我们不用的时候,一定要releaseCapture()来解放它。

在firefox中我们可以使用window.captureEvents(),火狐说这方法已经废弃,但我怎么在各标准浏览器中运作良好呢?!不过不管怎么样,来来回回要设置捕获与取消捕获非常麻烦与吃内存,我们需要转换思路。因为如果鼠标离开拖动元素上方,我们的绑定函数就无法运作,要是把它们绑定在document上呢,鼠标就无论在何处都能监听拖动元素。但触发拖动的onmousedown事件我们还保留在拖动元素上,这事件不会因为不执行就引起差错之虞。不过,由于绑定对象一变,我们要在这些事件中获得拖动对象的引用的难度就陡然加大,这里我就直接把它们做成构造函数内的私有函数吧。

01.var Drag = function(id){
02.  var el = document.getElementById(id);
03.  el.style.position = "absolute";    
04.  var drag = function(e) {
05.    e = e || window.event;
06.    el.style.cursor = "pointer";
07.    !+"\v1"? document.selection.empty() : window.getSelection().removeAllRanges();
08.    el.style.left = e.clientX - el.offset_x  + "px";
09.    el.style.top = e.clientY - el.offset_y  + "px";
10.    el.innerHTML = parseInt(el.style.left,10)+ "X"+parseInt(el.style.top,10);
11.  }
12.   
13.  var dragend = function(){
14.    document.onmouseup = null;
15.    document.onmousemove = null;
16.  }
17.    
18.  var dragstart = function(e){
19.    e = e || window.event;
20.    el.offset_x = e.clientX - el.offsetLeft;
21.    el.offset_y = e.clientY - el.offsetTop;
22.    document.onmouseup = dragend;
23.    document.onmousemove = drag;
24.    return false;
25.  }
26.  el.onmousedown = dragstart;
27.}

(责任编辑:admin)
织梦二维码生成器
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片