用javascript做拖动布局的思路

  哎!还是js的功夫太差。因为是边找资料边写的,很多地方印象不深,

  时间一长,再重新写估计也难,所以把当时的思路记录一下!也希望大虾指点一下!

  好了,转入正文,在开始之前先介绍几个功能函数!

  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;

  }

  好了,一个可以拖动布局的页面就完成了 查看最终页面效果

  能力有限,有些地方可能说的不清不楚,若有兴趣,自己好好看看代码吧。

  有什么不足的地方,请指教。

  演示代码:

  

   [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]