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

来源:互联网 发布:三一重工 大数据 编辑:程序博客网 时间:2024/06/04 23:31
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:偶的博客园的第一篇文章.望多多支持.
 
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 红米4x手机声音突然成破音怎么办 红米pro玩王者荣耀卡怎么办 红米手机恢复出厂设置出错了怎么办 红米恢复出厂设置出错了怎么办 应聘工作上当收押金了该怎么办 红米1s密码忘了怎么办 红米1s刷机后开不了机怎么办 红米2a耗电超快怎么办 红米2a手机耗电快怎么办 红米4x触屏失灵怎么办 苹果恢复出厂设置后密码忘记怎么办 红米1s忘记密码锁屏了怎么办 红米3手机忘记解锁图案怎么办 小米5x手机录屏失败怎么办 红米4x手机wif信号不好怎么办 红米4x屏幕换了截屏不好使怎么办 红米手机2a卡慢怎么办? 红米手机连接无线网信号不好怎么办 小米4用久了很卡怎么办 红米4a关不了机怎么办 红米手机屏幕锁了忘记密码怎么办 手机锁了忘记密码怎么办 红米 红米4a开不开机怎么办 红米显示小人开不了机怎么办 红米手机找回微信密码怎么办 红米手机密码忘了怎么办数字锁 红米1s忘了密码怎么办 红米手机下面三个键失灵怎么办 红米note手机没声音了怎么办 魅蓝3s被锁了怎么办 小米5x的4g网速慢怎么办 红米一体机与后盖有裂缝怎么办? 红米4x喇叭坏了怎么办 红米4x电池坏了怎么办 小米电视4a开不了机怎么办 小米x4手机下面三个键失灵怎么办 红米4a一直重启怎么办 红米4a手机一直关机重启怎么办 红米5A手机4G信号差怎么办 红米4x手机黑屏打不开怎么办 红米手机前置摄像头用不了怎么办