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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值