您的位置:首页 > Web前端 > JavaScript

javascript实现类似google和msn space的拖拽

2007-10-28 00:24 495 查看
javascript实现类似google和msn space的拖拽

[align=left] 最近在网上看到一些朋友到处找类似于google的个性主页和msn space的拖拽实现,在下正好也找到了一个例子.但是问题比较多.我将其改写并完善,建立了一个通用的函数.具体的函数实现如下:

<html>[/align]
[align=left]<head>[/align]
[align=left]<meta http-equiv="Content-Type" content="text/html; charset=gb2312">[/align]
[align=left]<title>BlackSoul的拖拽Demo</title>[/align]
[align=left]<!--[/align]
[align=left] ____________________________________[/align]
[align=left]|--------Author By BlackSoul---------|[/align]
[align=left]|------------2006.03.30--------------|[/align]
[align=left]|--------BlackSoulylk@gmail.com------|[/align]
[align=left]|------------QQ:9136194--------------|[/align]
[align=left]|------http://blacksoul.cnblogs.cn---|[/align]
[align=left]======================================[/align]
[align=left]-->[/align]
[align=left]<style type="text/css">[/align]
[align=left]body[/align]
[align=left]{[/align]
[align=left] margin:0px;[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]#aim /*设置目标层样式*/[/align]
[align=left]{[/align]
[align=left] position:absolute;/*控制层的位置所必须的style*/[/align]
[align=left] width:200px;[/align]
[align=left] height:30px;[/align]
[align=left] border:1px solid #666666;[/align]
[align=left] background-color:#FFCCCC;[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]#sourceLayer, #cloneLayer[/align]
[align=left]{[/align]
[align=left] position:absolute;/*控制层的位置所必须的style*/[/align]
[align=left] width:300px;[/align]
[align=left] height:50px;[/align]
[align=left] border:1px solid #666666;[/align]
[align=left] background-color:#CCCCCC;[/align]
[align=left] cursor:move;[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left].docked[/align]
[align=left]{[/align]
[align=left] display:none;[/align]
[align=left] filter:alpha(opacity=100);[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left].actived[/align]
[align=left]{[/align]
[align=left] display:block;[/align]
[align=left] filter:alpha(opacity=70);[/align]
[align=left]}[/align]
[align=left]</style>[/align]
[align=left]</head>[/align]
[align=left] [/align]
[align=left]<body >[/align]
[align=left] [/align]
[align=left]<div id="aim">放置范围</div>[/align]
[align=left]<div id="sourceLayer" unselectable="off"><img src="http://blacksoul.gamenews.cn/mail.png" alt="拖拽Demo">拖拽Demo源</div>[/align]
[align=left]<div id="cloneLayer" class="docked" unselectable="off"></div>[/align]
[align=left] [/align]
[align=left]<script type="text/javascript" language="javascript">[/align]
[align=left]<!--[/align]
[align=left]/*[/align]
[align=left] ====================================[/align]
[align=left]|--------Author By BlackSoul---------|[/align]
[align=left]|------------2006.03.30--------------|[/align]
[align=left]|--------BlackSoulylk@gmail.com------|[/align]
[align=left]|------------QQ:9136194--------------|[/align]
[align=left]|------http://blacksoul.cnblogs.cn---|[/align]
[align=left] ====================================[/align]
[align=left]*/[/align]
[align=left]//设置层对象[/align]
[align=left]var aim;[/align]
[align=left]var sourceLayer;[/align]
[align=left]var cloneLayer;[/align]
[align=left] [/align]
[align=left]//定义各个层初始位置[/align]
[align=left]var aimX;[/align]
[align=left]var aimY;[/align]
[align=left]var orgnX;[/align]
[align=left]var orgnY;[/align]
[align=left] [/align]
[align=left]//拖拽过程中的变量[/align]
[align=left]var draging = false; //是否处于拖拽中[/align]
[align=left]var offsetX = 0; //X方向左右偏移量[/align]
[align=left]var offsetY = 0; //Y方向上下偏移量[/align]
[align=left]var back; //返回动画对象[/align]
[align=left]var thisX ; //当前clone层的X位置[/align]
[align=left]var thisY ; //当前clone层的Y位置[/align]
[align=left]var time ;[/align]
[align=left]var stepX ; //位移速度[/align]
[align=left]var stepY ; //位移速度[/align]
[align=left] [/align]
[align=left]//初始化拖拽信息[/align]
[align=left]/*[/align]
[align=left] initAimX 目标x坐标[/align]
[align=left] initAimY 目标y坐标[/align]
[align=left] initOrgnX 拖拽源x坐标[/align]
[align=left] initOrgnY 拖拽源y坐标[/align]
[align=left]*/[/align]
[align=left]//获得层对象[/align]
[align=left] [/align]
[align=left]function getLayer(inAim,inSource,inClone)[/align]
[align=left]{[/align]
[align=left] aim = document.getElementById(inAim);[/align]
[align=left] sourceLayer = document.getElementById(inSource);[/align]
[align=left] cloneLayer = document.getElementById(inClone);[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]function initDrag(initAimX,initAimY,initOrgnX,initOrgnY)[/align]
[align=left]{[/align]
[align=left] aimX = initAimX;[/align]
[align=left] aimY = initAimY;[/align]
[align=left] orgnX = initOrgnX;[/align]
[align=left] orgnY = initOrgnY;[/align]
[align=left] //设置各个开始层的位置[/align]
[align=left] aim.style.pixelLeft = aimX;[/align]
[align=left] aim.style.pixelTop = aimY;[/align]
[align=left] sourceLayer.style.pixelLeft = orgnX;[/align]
[align=left] sourceLayer.style.pixelTop = orgnY;[/align]
[align=left] cloneLayer.style.pixelLeft = orgnX;[/align]
[align=left] cloneLayer.style.pixelTop = orgnY;[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]//准备拖拽[/align]
[align=left]function BeforeDrag()[/align]
[align=left]{[/align]
[align=left] if (event.button != 1)[/align]
[align=left] {[/align]
[align=left] return;[/align]
[align=left] }[/align]
[align=left] cloneLayer.innerHTML = sourceLayer.innerHTML; //复制拖拽源内容[/align]
[align=left] offsetX = document.body.scrollLeft + event.clientX - sourceLayer.style.pixelLeft;[/align]
[align=left] offsetY = document.body.scrollTop + event.clientY - sourceLayer.style.pixelTop;[/align]
[align=left] cloneLayer.className = "actived";[/align]
[align=left] draging = true;[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]//拖拽中[/align]
[align=left]function OnDrag()[/align]
[align=left]{[/align]
[align=left] if(!draging)[/align]
[align=left] {[/align]
[align=left] return;[/align]
[align=left] }[/align]
[align=left] //更新位置[/align]
[align=left] event.returnValue = false;[/align]
[align=left] cloneLayer.style.pixelLeft = document.body.scrollLeft + event.clientX - offsetX;[/align]
[align=left] cloneLayer.style.pixelTop = document.body.scrollTop + event.clientY - offsetY;[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]//结束拖拽[/align]
[align=left]function EndDrag()[/align]
[align=left]{[/align]
[align=left] if (event.button != 1)[/align]
[align=left] {[/align]
[align=left] return;[/align]
[align=left] }[/align]
[align=left] draging = false;[/align]
[align=left] [/align]
[align=left] if (event.clientX >= aim.style.pixelLeft && event.clientX <= (aim.style.pixelLeft + aim.offsetWidth) &&[/align]
[align=left] event.clientY >= aim.style.pixelTop && event.clientY <= (aim.style.pixelTop + aim.offsetHeight))[/align]
[align=left] {[/align]
[align=left] //拖拽层位于目标中,自动定位到目标位置[/align]
[align=left] sourceLayer.style.pixelLeft = aim.style.pixelLeft;[/align]
[align=left] sourceLayer.style.pixelTop = aim.style.pixelTop;[/align]
[align=left] cloneLayer.className = "docked";[/align]
[align=left] /*[/align]
[align=left] ** 这里完成之后可以用xml保存当前位置.[/align]
[align=left] ** 下次用户进入的时候[/align]
[align=left] ** 就初始化源拖拽层为xml当中的数据了 [/align]
[align=left] */[/align]
[align=left] }[/align]
[align=left] else[/align]
[align=left] {[/align]
[align=left] //拖拽位于目标层外,将拖拽源位置复原[/align]
[align=left] thisX = cloneLayer.style.pixelLeft;[/align]
[align=left] thisY = cloneLayer.style.pixelTop;[/align]
[align=left] offSetX = Math.abs(thisX - orgnX);[/align]
[align=left] offSetY = Math.abs(thisY - orgnY);[/align]
[align=left] time = 500;//设置动画时间[/align]
[align=left] stepX = Math.floor((offSetX/time)*20);[/align]
[align=left] stepY = Math.floor((offSetY/time)*20);[/align]
[align=left] if(stepX == 0)[/align]
[align=left] stepX = 2;[/align]
[align=left] if(stepY == 0)[/align]
[align=left] stepY = 2;[/align]
[align=left] [/align]
[align=left] //开始返回动画[/align]
[align=left] moveStart();[/align]
[align=left] } [/align]
[align=left]}[/align]
[align=left] [/align]
[align=left] [/align]
[align=left]function moveStart()[/align]
[align=left]{[/align]
[align=left] back = setInterval("MoveLayer();",15);[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]//设置返回的动画效果[/align]
[align=left]function MoveLayer()[/align]
[align=left]{[/align]
[align=left] //位于目标左上[/align]
[align=left] if(cloneLayer.style.pixelLeft <= orgnX && cloneLayer.style.pixelTop <= orgnY)[/align]
[align=left] {[/align]
[align=left] cloneLayer.style.pixelLeft += stepX;[/align]
[align=left] cloneLayer.style.pixelTop += stepY;[/align]
[align=left] //如果位移超过目标则设置速度为pix.并向反方向回移.此处实现了弹簧效果.下同[/align]
[align=left] if(cloneLayer.style.pixelLeft > orgnX)[/align]
[align=left] {[/align]
[align=left] stepX = 1;[/align]
[align=left] }[/align]
[align=left] if(cloneLayer.style.pixelTop > orgnY)[/align]
[align=left] {[/align]
[align=left] stepY = 1;[/align]
[align=left] }[/align]
[align=left] //在X或Y轴上坐标相同则不发生位移[/align]
[align=left] if(cloneLayer.style.pixelLeft == orgnX)[/align]
[align=left] {[/align]
[align=left] stepX = 0;[/align]
[align=left] }[/align]
[align=left] if(cloneLayer.style.pixelTop == orgnY)[/align]
[align=left] {[/align]
[align=left] stepY = 0;[/align]
[align=left] }[/align]
[align=left] if(cloneLayer.style.pixelLeft == orgnX && cloneLayer.style.pixelTop == orgnY)[/align]
[align=left] {[/align]
[align=left] EndMove();[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] //位于目标左下[/align]
[align=left] else if(cloneLayer.style.pixelLeft <= orgnX && cloneLayer.style.pixelTop >= orgnY)[/align]
[align=left] {[/align]
[align=left] cloneLayer.style.pixelLeft += stepX;[/align]
[align=left] cloneLayer.style.pixelTop -= stepY;[/align]
[align=left] if(cloneLayer.style.pixelLeft > orgnX)[/align]
[align=left] {[/align]
[align=left] stepX = 1;[/align]
[align=left] }[/align]
[align=left] if(cloneLayer.style.pixelTop < orgnY)[/align]
[align=left] {[/align]
[align=left] stepY = 1;[/align]
[align=left] }[/align]
[align=left] if(cloneLayer.style.pixelLeft == orgnX)[/align]
[align=left] {[/align]
[align=left] stepX = 0;[/align]
[align=left] }[/align]
[align=left] if(cloneLayer.style.pixelTop == orgnY)[/align]
[align=left] {[/align]
[align=left] stepY = 0;[/align]
[align=left] }[/align]
[align=left] if(cloneLayer.style.pixelLeft == orgnX && cloneLayer.style.pixelTop == orgnY)[/align]
[align=left] {[/align]
[align=left] EndMove();[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] //位于目标右上[/align]
[align=left] else if(cloneLayer.style.pixelLeft >= orgnX && cloneLayer.style.pixelTop <= orgnY)[/align]
[align=left] {[/align]
[align=left] cloneLayer.style.pixelLeft -= stepX;[/align]
[align=left] cloneLayer.style.pixelTop += stepY;[/align]
[align=left] if(cloneLayer.style.pixelLeft < orgnX)[/align]
[align=left] {[/align]
[align=left] stepX = 1;[/align]
[align=left] }[/align]
[align=left] if(cloneLayer.style.pixelTop > orgnY)[/align]
[align=left] {[/align]
[align=left] stepY = 1;[/align]
[align=left] }[/align]
[align=left] if(cloneLayer.style.pixelLeft == orgnX)[/align]
[align=left] {[/align]
[align=left] stepX = 0;[/align]
[align=left] }[/align]
[align=left] if(cloneLayer.style.pixelTop == orgnY)[/align]
[align=left] {[/align]
[align=left] stepY = 0;[/align]
[align=left] }[/align]
[align=left] if(cloneLayer.style.pixelLeft == orgnX && cloneLayer.style.pixelTop == orgnY)[/align]
[align=left] {[/align]
[align=left] EndMove();[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] //位于目标右上[/align]
[align=left] else if(cloneLayer.style.pixelLeft >= orgnX && cloneLayer.style.pixelTop >= orgnY)[/align]
[align=left] {[/align]
[align=left] cloneLayer.style.pixelLeft -= stepX;[/align]
[align=left] cloneLayer.style.pixelTop -= stepY;[/align]
[align=left] if(cloneLayer.style.pixelLeft < orgnX)[/align]
[align=left] {[/align]
[align=left] stepX = 1;[/align]
[align=left] }[/align]
[align=left] if(cloneLayer.style.pixelTop < orgnY)[/align]
[align=left] {[/align]
[align=left] stepY = 1;[/align]
[align=left] }[/align]
[align=left] if(cloneLayer.style.pixelLeft == orgnX)[/align]
[align=left] {[/align]
[align=left] stepX = 0;[/align]
[align=left] }[/align]
[align=left] if(cloneLayer.style.pixelTop == orgnY)[/align]
[align=left] {[/align]
[align=left] stepY = 0;[/align]
[align=left] }[/align]
[align=left] if(cloneLayer.style.pixelLeft == orgnX && cloneLayer.style.pixelTop == orgnY)[/align]
[align=left] {[/align]
[align=left] EndMove();[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] //到达目标[/align]
[align=left] else[/align]
[align=left] {[/align]
[align=left] EndMove();[/align]
[align=left] }[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]//停止返回动画[/align]
[align=left]function EndMove()[/align]
[align=left]{[/align]
[align=left] sourceLayer.style.pixelLeft = orgnX;[/align]
[align=left] sourceLayer.style.pixelTop = orgnY;[/align]
[align=left] cloneLayer.style.pixelLeft = orgnX;[/align]
[align=left] cloneLayer.style.pixelTop = orgnY;[/align]
[align=left] cloneLayer.className = "docked";[/align]
[align=left] clearInterval(back);[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]//主拖拽函数[/align]
[align=left]function startDraging(inAim,inSource,inClone,initAimX,initAimY,initOrgnX,initOrgnY)[/align]
[align=left]{[/align]
[align=left] getLayer(inAim,inSource,inClone)[/align]
[align=left] initDrag(initAimX,initAimY,initOrgnX,initOrgnY);[/align]
[align=left] sourceLayer.onmousedown = BeforeDrag;[/align]
[align=left] document.onmousemove = OnDrag; //这里如果用cloneLayer,在拖拽中会选中cloneLayer里面内容,进而出现一些bug...[/align]
[align=left] cloneLayer.onmouseup = EndDrag; [/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]//调用[/align]
[align=left]startDraging("aim","sourceLayer","cloneLayer",300,200,20,20);[/align]
[align=left]//-->[/align]
[align=left]</script>[/align]
[align=left]</body>[/align]
[align=left]</html>

需要注意的是:
一.html里面对于div的定义需要有三个. 三个层都必须定义style的position为absolute,以便控制位置
1.目标层(aim),主要作用是定义拖拽生效的位置.
2.拖拽源(sourceLayer).注意设置属性unselectable = "off"(这里比较奇怪,设置成on范围会在拖拽过程中选中层内容)
3.用于复制的层(cloneLayer).
二.函数的调用
startDraging参数解释:
initAim 目标层名称 initSource 拖拽源名称 initClone 用于复制的层的名称
initAimX 目标层x轴坐标 initAimY 目标层y轴坐标 initOrgnX 拖拽源x坐标 initOrgnY 拖拽源Y轴坐标

仅IE里面测试通过.代码里面添加了注释.可以在拖拽源到达目标之后添加写xml的操作.进而记录用户自定义页面排版的数据.对于返回动画的算法还不是很满意.希望各位多多提些建议.以便完善.小弟当前致力于开发一套基于asp.net2.0的ajax控件.希望多多交流.

ps:偶的博客园的第一篇文章.望多多支持.[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: