用javascript做拖動布局的思路

來源:互聯網
上載者:User

好了,轉入本文,在開始之前先介紹幾個功能函數!
1.格式化事件的函數 複製代碼 代碼如下:function getEvent(){
//同時相容ie和ff的寫法
if(document.all) return window.event;
func=getEvent.caller;
while(func!=null){
var arg0=func.arguments[0];
if(arg0){
if((arg0.constructor==Event || arg0.constructor ==MouseEvent)
|| (typeof(arg0)=="object" && arg0.preventDefault && arg0.stopPropagation)){
return arg0;
}
}
func=func.caller;
}
return null;
}

2.取得滑鼠的位置

複製代碼 代碼如下:

function mouseCoords(ev){
if(ev.pageX || ev.pageY){
return {x:ev.pageX, y:ev.pageY};
}
return {
x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
y:ev.clientY + document.body.scrollTop - document.body.clientTop
};
}

3.得到元素的位置
複製代碼 代碼如下:function getPosition(ele){
var left = 0;
var top = 0;
while (ele.offsetParent){
left += ele.offsetLeft;
top += ele.offsetTop;
ele = ele.offsetParent;
}
left += ele.offsetLeft;
top += ele.offsetTop;
return {x:left, y:top};
}

首先,當然是寫好初始布局的頁面, 查看初始頁面效果

一般拖動的元素是跟隨滑鼠的,我的思路是在把拖動的元素增加到一個position為absolute的div中,
滑鼠拖動的時候就讓它的位置根據滑鼠的座標變化就可以了。所以在頁面增加了個onload

複製代碼 代碼如下:var tmpDiv=null;//臨時存放拖動對象的div
window.onload=function(){
tmpDiv=document.createElement("div");
tmpDiv.style.cssText = 'position:absolute;display:none;border:1px dotted #FFCC66;';
document.body.appendChild(tmpDiv);
}

要實現拖動,首先觸發的事件是mouseDown,所以我在拖動的table的一個td上綁定了onmousedown="mouseDown(this);"

程式碼

複製代碼 代碼如下:var dragObject = null;//拖動的元素(table)
var mouseOffset = null;//滑鼠的在拖動元素中的位置
var dragDiv=null;//拖動的table所在的列的div
var eleDivW=null;//拖動的table的父節點(div)的高度
var dragDivLen=null;//拖動的table所在的列的div中用來放置table的div的個數
var DragContainer=["col1","col2","col3"];//用來實現列布局的div的id
//滑鼠按下拖動的元素
function mouseDown(elem){
ev=getEvent();
dragObject = elem.parentNode.parentNode.parentNode;//被拖動的table
dragDiv=dragObject.parentNode.parentNode;
//拖動元素所在列裡div的個數
dragDivLen=dragDiv.getElementsByTagName("div").length;
mouseOffset = getMouseOffset(dragObject, ev);
eleDivW=dragObject.parentNode.offsetWidth;
dragObject.parentNode.style.border="1px dotted #FFCC66";
return false;
}
//得到滑鼠在拖動元素中的位置
function getMouseOffset(target, ev){
var docPos = getPosition(target);
var mousePos = mouseCoords(ev);
return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
}

剩下的當然就是滑鼠移動拖動對象也能移動,用到的當然就是mouseMove咯,為簡單我在document上綁定,

複製代碼 代碼如下:document.onmousemove = mouseMove;
function mouseMove(){
ev=getEvent();
var mousePos = mouseCoords(ev);
if(dragObject){
dragObject.parentNode.style.display="none";//設定放置被拖動table的div隱藏
//把拖動的table放到臨時的div中,並設定其座標
for(var i=0; i<tmpDiv.childNodes.length; i++) tmpDiv.removeChild(tmpDiv.childNodes[i]);
tmpDiv.appendChild(dragObject.cloneNode(true));
tmpDiv.style.width=eleDivW+"px";
tmpDiv.style.backgroundColor="#FFFFFF";
tmpDiv.style.display="block";
tmpDiv.style.top = (mousePos.y - mouseOffset.y)+"px";
tmpDiv.style.left = (mousePos.x - mouseOffset.x)+"px";
}
return false;
}

有了mousemove當然少不了mouseup 複製代碼 代碼如下:document.onmouseup = mouseUp;
//滑鼠鬆開
function mouseUp(){
if(dragObject){
if(dragObject.parentNode.style.display=="none") dragObject.parentNode.style.display="block";
dragObject.parentNode.style.border="1px solid #FFCC66";
tmpDiv.style.display="none";
//這裡是判斷當列裡有可拖動的元素時清除前面設定的高度值20px
for(var m=0;m<DragContainer.length;m++){
var colDiv=document.getElementById(DragContainer[m]);
var colDivLen=colDiv.getElementsByTagName("div").length
var colSty=colDiv.getAttribute("style");
if(colDivLen>0&&colSty!=null){
colDiv.removeAttribute("style");
break;
}
}
dragObject=null;
}
}

看看是不是可以拖動了,當你鬆開滑鼠左鍵時,拖動的元素將回到原來的位置 查看拖動頁面效果

最後要做的就是讓拖動元素不回到原來的位置,而是回到我們拖動的位置。
下面是mousemove事件的所有代碼,看看注釋就明白了 複製代碼 代碼如下:function mouseMove(){
ev=getEvent();
var mousePos = mouseCoords(ev);
if(dragObject){
//可拖動的個數為1,說明拖動後此列就沒有拖動元素,為避免此列沒有高度而不見,所以設定其高度為20px
if(dragDivLen==1) dragDiv.style.height="20px";
dragObject.parentNode.style.display="none";
//把拖動的元素加入到臨時的tmpDiv中,並設定tmpDiv座標
for(var i=0; i<tmpDiv.childNodes.length; i++) tmpDiv.removeChild(tmpDiv.childNodes[i]);
tmpDiv.appendChild(dragObject.cloneNode(true));
tmpDiv.style.width=eleDivW+"px";
tmpDiv.style.backgroundColor="#FFFFFF";
tmpDiv.style.display="block";
tmpDiv.style.top = (mousePos.y - mouseOffset.y)+"px";
tmpDiv.style.left = (mousePos.x - mouseOffset.x)+"px";
//被拖動對象的中心點的座標
var dragObjCntX=mousePos.x - mouseOffset.x+parseInt(dragObject.offsetWidth)/2;
var dragObjCntY=mousePos.y - mouseOffset.y+parseInt(dragObject.offsetHeight)/2;
//判斷tmpDiv所在的列
var dragConLen=DragContainer.length;
for(var i=0;i<dragConLen;i++){
var curContainer=document.getElementById(DragContainer[i]);
var dcPos=getPosition(curContainer);
var dcPosMinX=dcPos.x;
var dcPosMinY=dcPos.y;
var dcWidth=curContainer.offsetWidth;
var dcHeight=curContainer.offsetHeight;
var dcPosMaxX=dcPosMinX+dcWidth;
var dcPosMaxY=dcPosMinY+dcHeight;
if(dragObjCntX>dcPosMinX&&dragObjCntX<dcPosMaxX&&dragObjCntY>dcPosMinY&&dragObjCntY<dcPosMaxY){
var activeContainer=curContainer;
break;
}
}
}
//判斷tmpDiv在此列哪個區塊範圍內
if(activeContainer){
var beforNode=null;
var sDiv=activeContainer.getElementsByTagName("div")
var acChiLen=sDiv.length;
for(j=acChiLen-1;j>=0;j--){
var activeDiv=sDiv[j];
if(activeDiv){
var activeDivPos=getPosition(activeDiv);
var activeDivMinX=activeDivPos.x;
var activeDivMinY=activeDivPos.y;
var activeDivMaxX=activeDivMinX+activeDiv.offsetWidth;
var activeDivMaxY=activeDivMinY+activeDiv.offsetHeight;
if(activeDivMaxX>dragObjCntX&&activeDivMaxY>dragObjCntY){
//if(dragObjCntX>activeDivMinX&&dragObjCntX<activeDivMaxX&&dragObjCntY>activeDivMinY&&dragObjCntY<activeDivMaxY){
beforNode=activeDiv;
}
}

}
//若此區塊存在,就在此區塊前插入拖動元素
if(beforNode!=null){
if(dragObject.parentNode!=beforNode){
curContainer.insertBefore(dragObject.parentNode,beforNode);
dragObject.parentNode.style.display="block";
//document.getElementById("test").value=curContainer.id;
}
}
//不存在就在所在列插入拖動元素
else{
curContainer.appendChild(dragObject.parentNode);
dragObject.parentNode.style.display="block";
}
}
return false;
}

好了,一個可以拖動布局的頁面就完成了 查看最終頁面效果

能力有限,有些地方可能說的不清不楚,若有興趣,自己好好看看代碼吧。
有什麼不足的地方,請指教。

相關文章

聯繫我們

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

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

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.