JS实现节点可拖动的树

<html>

<head>

<title></title>

<style>

body{

margin:0px;

}

#dragDiv{position:absolute;display:none;background-color:#3366cc;color:#ffffff;}

.title{border:0px;font-size:16px;}

.node{padding-left:20px;overflow:hidden;}

.icon{display:inline;margin-right:5px;cursor:pointer;}

</style>

<script type="text/javascript" src="tree.js"></script>

<script type="text/javascript" language="javascript">

TreeView = function(Root)

{

 this.root = document.getElementById(Root);

 var _this = this;

 if(this.root == null)

 {

  alert('Invalid tree root!');

  return false;

 }

    this.init = function()

    {

     document.onmousedown = _this.DragStart;

     document.onmouseup = _this.DragStop;

     document.onmousemove = _this.Draging;

    }

 //每个nodeId必须是唯一的合法的html元素Id,且不能以_title,_icon,_child之类的结尾

 this.addNode = function(parentId,nodeId,nodeName,link)

 {

  var oParent = document.getElementById(parentId);

  //父节点合法不?

  if(oParent == null) return;

  var oNode = document.createElement('div');

  oNode.id = nodeId;

  oNode.className = 'node';

  //真够费劲的

  oNode.innerHTML = "<div id='"+nodeId+"_title' class='title'><span class='icon' οnclick='Tree.fold(this)'>-</span>"+nodeName+"</div>";

  oParent.appendChild(oNode);

 }

 this.DragStart = function(e)

 {

  e = e || window.event;

  this.DragObj = e.target || e.srcElement;

  //是否是合法的节点?

  if(this.DragObj.className != 'title')return;

  this.tmpNode = document.getElementById('dragDiv');

  this.tmpNode.innerHTML = this.DragObj.lastChild.nodeValue;

  this.DragObj = this.DragObj.parentNode;

  //debug('drag start:'+this.DragObj.id+':'+this.DragObj.className);

  this.indrag = true;

  this.x = e.pageX || (e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft));

     this.y = e.pageY || (e.clientY + (document.documentElement.scrollTop || document.body.scrollTop));

  this.left = parseInt(this.tmpNode.offsetLeft);

  this.top = parseInt(this.tmpNode.offsetTop);

  //这里一定要return false啊,否则,嘿嘿,我不告诉你,你可以拖拖看。

  return false;

 }

 this.DragStop = function(e)

 {

  if(!this.indrag)return;

  this.indrag = false;

  this.tmpNode.style.display = 'none';

  e = e || window.event;

  var target = e.target || e.srcElement;

  if(target.className != 'title')return;

  try{

   target.parentNode.appendChild(this.DragObj);

  }

  catch(e)

  {

   //alert('出错啦!');

  }

  return true;

 }

 this.Draging = function(e)

 {

  if(!this.indrag)return;

  e = e || window.event;

  _this.autoScroll(e);

  var x = e.pageX || (e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft));

     var y = e.pageY || (e.clientY + (document.documentElement.scrollTop || document.body.scrollTop));

    

  this.tmpNode.style.left = x+2+'px';

  this.tmpNode.style.top = y+2+'px';

  this.tmpNode.style.display = 'block';

  //这里也要return false啊

  return false;

 }

 this.fold = function(element)

 {

  if(element.innerHTML == '+')

  {

   element.parentNode.parentNode.style.height = '';

   element.innerHTML = '-';

  }

  else

  {

   element.innerHTML = '+';

   element.parentNode.parentNode.style.height = element.parentNode.offsetHeight;

  }

  return false;

 }

 this.autoScroll = function(e)

 {

     var step = 10;

     //var ww = window.innerWidth || document.body.clientWidth;

     var wh= window.innerHeight || document.body.clientHeight;

    

     if(e.clientY<20)

     {

            window.scrollBy(0,-step);

        }

        else if(e.clientY > wh-20)

        {

            window.scrollBy(0,step);

        }

 }

 return this;

}

var Tree = null;

function page_onload()

{

 Tree = new TreeView('TreeRoot');

 Tree.init();

 Tree.addNode('TreeRoot','test_0','test_0','test_0');

 for(i=1;i<100;i++)

 {

  Tree.addNode('test_'+Math.floor(Math.random()*i),'test_'+i,'test_'+i,'test_'+i);

 }

}

window.onload = page_onload;

function debug(msg)

{

 var d = new Date();

 document.getElementById('debugger').innerHTML+= d.getHours()+':'+d.getMinutes()+':'+d.getSeconds()+'->'+msg+'<br />';

}

</script>

</head>

<body>

simple but useful.

<div id="dragDiv"></div>

<div id="TreeRoot" class="node">

 <div id="TreeRoot_title" class="title"><span class="icon" οnclick="Tree.fold(this)">-</span>Root</div>

 <div id="TreeNode01" class="node">

  <div id="TreeNode01_title" class="title"><span class="icon" οnclick="Tree.fold(this)">-</span>Node01</div>

 </div>

 <div id="TreeNode02" class="node">

  <div id="TreeNode02_title" class="title"><span class="icon" οnclick="Tree.fold(this)">-</span>Node02</div>

  <div id="TreeNode11" class="node">

   <div id="TreeNode11_title" class="title"><span class="icon" οnclick="Tree.fold(this)">-</span>Node11</div>

  </div>

  <div id="TreeNode12" class="node">

   <div id="TreeNode12_title" class="title"><span class="icon" οnclick="Tree.fold(this)">-</span>Node12</div>

  </div>

 </div>

</div>

<div id="debugger" style="position:absolute;top:0px;right:0px;border:1px solid black; overflow:auto;height:400px;width:200px;"></div>

</body>

</html>

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值