最近在網上看到一些朋友到處找類似于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=" <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> 需要注意的是: 僅IE里面測試通過.代碼里面添加了注釋.可以在拖拽源到達目標之后添加寫xml的操作.進而記錄用戶自定義頁面排版的數據.對于返回動畫的算法還不是很滿意.希望各位多多提些建議.以便完善.小弟當前致力于開發一套基于asp.net
一.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軸坐標
ps:偶的博客園的第一篇文章.望多多支持.
http://blacksoul.cnblogs.com/archive/2006/03/31/363463.html
新聞熱點
疑難解答