javascript實作類別似google和msn space的拖拽

來源:互聯網
上載者:User
google

     最近在網上看到一些朋友到處找類似於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="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:偶的部落格園的第一篇文章.望多多支援.


http://blacksoul.cnblogs.com/archive/2006/03/31/363463.html



相關文章

Cloud Intelligence Leading the Digital Future

Alibaba Cloud ACtivate Online Conference, Nov. 20th & 21st, 2019 (UTC+08)

Register Now >

Starter Package

SSD Cloud server and data transfer for only $2.50 a month

Get Started >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。