最近在網路上看到一些朋友到處找類似於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---------- ----|
|[email protected] ------|
|------------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>
<身體 >
<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----- ---------|
|[email protected] ------|
|------------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.pixel;
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= (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);
= 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.pixelLeft += stepX; cloneLayer.style.pixelLeft += stepX; cloneLayer.style.pixelLeft += stepX;cloneLayer.style.pixelLeft
+= stepX;
.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 -= stopYyer
if(clonestyle. .pixelLeft > orgnX)
{
stepX = 1;
}
if(cloneLayer.style.pixelTop < orgnY)
{
stepY = 1;
}
if(cloneLayer.style.pixelLeft == orgnX)
{
stepX = 0;
}
if(clonestyle. 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 += stepLayer
if(clonestyle. .pixelLeft < orgnX)
{
stepX = 1;
}
if(cloneLayer.style.pixelTop > orgnY)
{
stepY = 1;
}
if(cloneLayer.style.pixelLeft == orgnX)
{
stepX = 0;
}
if(clonestyle. 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 -= stopYyer
if(clonestyle. .pixelLeft < orgnX)
{
stepX = 1;
}
if(cloneLayer.style.pixelTop < orgnY)
{
stepY = 1;
}
if(cloneLayer.style.pixelLeft == orgnX)
{
stepX = 0;
}
if(clonestyle. 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 = orgnYclass;
clearInterval(back);
}
//主拖曳函數
function startDraging(inAim,inSource,inClone,initAimX,initAimY,initOrgnX,initOrgnY)
{
getLayer
(inAim,inSource,inClone)
initDrag(initAimX,initAimt,in,in,8r888
;
.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:偶的博客園的第一篇文章.望多多支持.