ajax + div +js +xml+ servlet 实现无限级动态目录树(原创)

虽然网上这方面的资料很多,但真正能用的几乎没有,而笔者最近在做开发的时候,实在找不到合适的。没办法,只好自己动手,丰衣足食了。。

这棵目录树,不仅实现了无限级动态目录.而且页面上可以通过右键菜单实现树节点的动态添加,删除和重命名.另外还支持节点之间的拖放操作.因为基于ajax技术,所以所有操作都是无刷新的.

缺点:因为时间紧迫,所以开发的时候,代码质量估计不是很高,另外,xml文件是一次性从数据库读取生成的,而不是随着节点的展开而读取数据,所以对于大数据量的访问是不适合的.

(真后悔啊, 花了n多时间,挂掉了n多脑细胞!!)。希望对大家有所帮助!!!

1。数据表结构

 

nodeid //节点id

nodename//节点名称

parentid//父节点id

childid //子节点id

 上面的字段类型都是varchar.根据项目了,设定为了11位

2.xml文件格式

noderoot id="" text="" parentid=""

node id="" text="" parentid=""

 xml 文件是从数据库里读取并由servlet动态生成的。除了根节点的 parentid 属性为空外,其他都是有数值的。

因为js是utf-8编码的,所以在servlet里面最好加上下面2句

response.setHeader("Cache-Control", "no-cache");
  response.setContentType("text/xml;charset=utf-8");

3.ajax.js

js 代码
  1. var req = new function()   
  2. {   
  3.     this.xhr = null;   
  4.     this.xmldata = null;    
  5.     this.userid = null;   
  6.        
  7.   this.createInstance = function()    
  8.   {   
  9.     var instance = null;   
  10.     try    
  11.     {   
  12.         instance = new ActiveXObject("Msxml2.XMLHTTP");   
  13.     }   
  14.     catch(e)    
  15.     {   
  16.         try    
  17.         {   
  18.          instance = new ActiveXObject("Microsoft.XMLHTTP");   
  19.         }   
  20.         catch(E)    
  21.         {   
  22.          instance = false;   
  23.         }   
  24.     }   
  25.        
  26.     if(!instance && typeof XMLHTTPRequest != 'undefined')    
  27.     {   
  28.         instance = new XMLHTTPRequest();   
  29.         if (instance.overrideMimeType)   
  30.         {   
  31.             instance.overrideMimeType="text/xml";   
  32.         }   
  33.     }   
  34.     return instance;   
  35.   }   
  36.     
  37.     this.getxmldata= function()    
  38.     {   
  39.         this.userid = arguments[0];   
  40.         xhr = this.createInstance();   
  41.         xhr.onreadystatechange=this.buildxmltree;   
  42.         xhr.open("GET","/getdatafromXML?userid="+arguments[0],true);   
  43.         xhr.send(null);   
  44.     }   
  45.        
  46.     this.buildxmltree = function()    
  47.     {   
  48.         if(xhr.readyState==4)    
  49.         {    
  50.             if(xhr.status==200)   
  51.             {   
  52.                 req.xmldata = xhr.responseText;   
  53.                 var o = new ActiveXObject('Microsoft.XMLDOM');   
  54.                 o.async = false;   
  55.                 o.loadXML(req.xmldata);   
  56.                 req.doXMLMsg(o);   
  57.             }   
  58.             else    
  59.             {   
  60.                 //deal the error here   
  61.             }   
  62.         }   
  63.     }   
  64.   
  65.     this.doXMLMsg = function(obj)    
  66.     {   
  67.         treeview.data = obj;   
  68.         treeview.xhr = req.xhr;   
  69.         treeview.userid = req.userid;   
  70.         treeview.init();   
  71.     }   
  72.        
  73. }  

 

4.treeview.js

var treeview = new function() {
 this.data = null;
 this.xhr = null;
 this.userid = null;
 this.icon=new Array();
 this.icon["leaf"]='/Doc/images/child.gif';
this.icon["open"]='/Doc/images/opened.gif';
 this.icon["close"]='/Doc/images/closed.gif';
 this.user = null;
 this.rootid = null;
 this.root = null;
 this.dragElement = null;
 this.currElement = null;
 this.dragid = null;
 this.targetid = null;
 this.rightmenu = null;
 this.dragPath = null;
 this.jink = "no";
 
 this.init = function() {
  this.user = this.data.getElementsByTagName("noderoot")[0].getAttribute("text");
  this.rootid = this.data.getElementsByTagName("noderoot")[0].getAttribute("id");
 this.root = document.createElement("div");
  this.root.roll = 0;
  this.root.style.position="relative";
 this.root.style.display="block";
 this.root.innerHTML="";
  this.root.innerHTML+='';
  this.root.innerHTML+=''+this.user+'';
  this.root.οndragstart=treeview.dragstart;
  this.root.οndragοver=treeview.dragover;
  this.root.οndrοp=treeview.drop;
  this.root.οndragend=treeview.dragend;
  this.root.οnmοusedοwn=treeview.selectText;
  document.body.appendChild(this.root);

 this.rightmenu = document.createElement("div");
  this.rightmenu.id = "menu";
  this.rightmenu.style.position="absolute";
  this.rightmenu.style.width="30px";
 this.rightmenu.style.height="60px";
  this.rightmenu.style.display="none";
  document.body.appendChild(this.rightmenu);
  
     var obj = this.data.documentElement;
    if(obj.hasChildNodes()) {
  var i;
  var nodes = obj.childNodes;
   for(i=0;i #    var el = document.createElement("div");
    el.innerHTML="";
   var subObj = nodes.item(i);
    var subid = subObj.getAttribute("id");
    el.roll = 0;
   el.style.position="relative";
    el.style.marginLeft="14px";
   el.style.display="none";
   if(subObj.hasChildNodes()) {
    el.innerHTML+='';
   el.innerHTML+=''+subObj.getAttribute("text")+'';
       this.root.appendChild(el);
     this.showChilds(subObj,el);
    }else {
    el.innerHTML+='';
     el.innerHTML+=''+subObj.getAttribute("text")+'';
     this.root.appendChild(el);
    }
  }
  }          
 }

 this.showChilds=function(o,ev)
 {
  var i;
  var nodes = o.childNodes;
  for(i=0;i #  { 
   var el = document.createElement("div");
   el.innerHTML="";
   var subObj = nodes.item(i);
   var subid = subObj.getAttribute("id");
   el.roll = 0;
   el.style.position="relative";
   el.style.marginLeft="14px";
   el.style.display="none";
   if(subObj.hasChildNodes()) 
   {
    el.innerHTML+='';
    el.innerHTML+=''+subObj.getAttribute("text")+'';
       ev.appendChild(el);
                this.showChilds(subObj,el);
  }else 
   {
    el.innerHTML+='';
   el.innerHTML+=''+subObj.getAttribute("text")+'';
    ev.appendChild(el);
  }
  }
}

 this.addElement= function(id) {
  var obj = document.getElementById(id);
  var upObj = obj.parentNode;
  var o = arguments[1];
  if(o) {
   var subObj=o.childNodes.item(1);         
        subObj.setAttribute("parentid",id);
   upObj.appendChild(o);   
   if(upObj.getAttribute("roll")==0) 
   {
    upObj.childNodes.item(0).setAttribute("src",treeview.icon["open"]);
  } 
         var subid = subObj.getAttribute("id");
      xhr.open("GET","/addElement?parentid="+id+"&nodeid="+subObj.getAttribute("id")+"&nodename="+subObj.getAttribute("name")+"&path="+treeview.getfullpath(subObj.getAttribute("id"),""));
     xhr.send(null);
      return;
  } 
 }
 
 this.deleteElement=function(valueid) {
  menu.style.display="none";
 var delPath = treeview.getfullpath(valueid,"");
  var obj = document.getElementById(valueid);
  var parentid = obj.getAttribute("parentid");
  var upObj = document.getElementById(parentid);
  var oEle = obj.parentNode.getElementsByTagName("div");
 if(oEle.length!=0)
  {
   var i;
   for(i=0;i #   {
    var subObj = oEle.item(i);
   if(subObj.parentNode==obj.parentNode)
   {
     this.deleteChilds(subObj);
     obj.parentNode.removeChild(subObj);
   }
   } 
 }
  upObj.parentNode.removeChild(obj.parentNode);
  oEle = upObj.parentNode.getElementsByTagName("DIV");
  var bool = upObj.parentNode.childNodes.item(1).getAttribute("parentid");
  if(oEle.length==0)
  {
   if((bool!="")&&(bool!=null)) {
    upObj.parentNode.childNodes.item(0).setAttribute("src",treeview.icon["leaf"]);
       upObj.parentNode.setAttribute("roll",0);
  }
  }
 xhr.open("GET","/delElement?id="+valueid+"&parentid="+parentid+"&subPath="+delPath);
  xhr.send(null); 
  
 }
 
 this.deleteChilds=function(o) {
  var oEle = o.getElementsByTagName("DIV");
  if(oEle.length!=0)
  {
   var i;
   for(i=0;i #   {
    var subObj = oEle.item(i);
    if(subObj.parentNode==o)
    {
    this.deleteChilds(subObj);
     o.removeChild(subObj);
   }
   }
  } 
 }
 
 this.rename=function(nameid) {
  menu.style.display="none";
  var path = treeview.getfullpath(nameid,"");
  var obj = document.getElementById(nameid);
 var result = prompt("please input a new name","");
  if(result!=null) {
   obj.setAttribute("name",result);
   obj.innerText=result;
  }
  xhr.open("GET","/rename?name="+result+"&nameid="+nameid+"&path="+path+"&upPath="+treeview.getfullpath(obj.getAttribute("parentid"),""));
  xhr.send(null);
 }
 
 this.selectText=function() 
 {
  var o = window.event.srcElement;
  if(o.tagName!="SPAN") {
   return;
  }
 var ra = document.body.createTextRange();   
        ra.moveToElementText(o); 
        ra.select();     
        window.event.cancelBubble = true;
 }
 
 this.dragstart=function() 
 {
  var o = window.event.srcElement;
 if(o.tagName != "SPAN") 
  {
   return false;
  }
 this.dragid = o.getAttribute("id");
  this.dragPath = treeview.getfullpath(this.dragid,"");
 this.dragElement = o.parentNode;
  var length = treeview.childNodeNum(this.dragElement.parentNode);
  if(length==1)
  {
   this.dragElement.parentNode.childNodes.item(0).setAttribute("src",treeview.icon["leaf"]);
  }
 }
 
 this.dragover=function() {
  if(!this.dragElement.contains(window.event.srcElement)) {
   if(window.event.srcElement.tagName=="DIV")
  {
    this.currElement = window.event.srcElement;
   }
   else
   {
    this.currElement = window.event.srcElement.parentNode;
  }
            window.event.returnValue = false;
  }
 }
 
 this.drop=function() {
  this.targetid = this.currElement.childNodes.item(1).getAttribute("id");
  this.currElement.appendChild(this.dragElement);
  this.dragElement.childNodes.item(1).setAttribute("parentid",this.currElement.childNodes.item(1).getAttribute("id"));
 }
 
 this.dragend=function() {
  var length = treeview.childNodeNum(this.currElement);
  if(length!=0)
  {
   this.currElement.childNodes.item(0).setAttribute("src",treeview.icon["open"]);
   this.currElement.setAttribute("roll",0);
  }
  xhr.open("GET","/dragElement?dragid="+this.dragid+"&targetid="+this.targetid+"&dragPath="+this.dragPath+"&targetPath="+treeview.getfullpath(this.dragid,""));
  xhr.send(null);
 }
 
 this.showDiv=function() {
  var o = window.event.srcElement;
  if(o.tagName!="SPAN") {
   if(o.tagName=="IMG") {
    o = o.parentNode.item(1);
   }else {
    o = o.item(1);
   }
  }
  var id = o.getAttribute("id");
  treeview.rightmenu.style.left=event.clientX;
  treeview.rightmenu.style.top=event.clientY; 
  
  var parent = o.getAttribute("parentid");

//这里的那段代码总是显示不出来,看源代码吧!

 this.getfullpath=function(nodeid,path) {//get the full path of the node
  var path = path;
  var node = document.getElementById(nodeid);
  path = "/"+node.getAttribute("name")+path;  
  var parentid = node.getAttribute("parentid");
  if(parentid!=null&&parentid!="") {
   path = this.getfullpath(parentid,path);
  }
  return path;
 }
 
 this.jinkpage=function() {
  var jink = arguments[0];
  var o = window.event.srcElement;
  if(o.tagName=="div") {
   o = o.childNodes.item(1);
  }else if(o.tagName=="img") {
   o = o.parentNode.childNodes.item(1);
  }
  var id = o.getAttribute("id");
  var pathway = treeview.getfullpath(id,"");
  if(jink=="no") {
   pathway = "abcdef";
  }
  parent.frames["right"].location.href="/Doc/jsp/showAllFileMsg.jsp?path="+pathway;
 }
 
 this.buildObj=function() {
  menu.style.display="none";
  var o = new Object();
  var id = this.userid.toString()+this.getRandomNumber();
  var result = prompt("please input a new name","");
  if(!result) {
   alert("the name can`t be null!!");
   result = prompt("please input a new name","");
  } 
  

js 代码
  1. o = document.createElement("div");   
  2.         o.roll = 0;   
  3.         o.style.position="relative";   
  4.         o.style.marginLeft="10px";   
  5.         o.style.padding = "2px";   
  6.         o.style.display="block";   
  7.         o.innerHTML='"treeview.divCtrl()" />';   
  8.         o.innerHTML+='"cursor:hand;height:20px" id='+id+' name='+result+' parentid=""'+' onClick="treeview.jinkpage()" οncοntextmenu="treeview.showDiv();return false">'+result+'';   
  9.         return o;  


 
 this.getRandomNumber=function() {
  var num = Math.round(10000*Math.random());
  return num;
 }
 
 this.divCtrl=function()
 {
  var o = window.event.srcElement;
  var img = o.getAttribute("src");
  img = img.substring(img.lastIndexOf("/")+1);
  if(img=="child.gif")
  {
   return;
  }
  var obj = o.parentNode;
  if(obj.getAttribute("roll")==0)
  {
   var oEle = obj.getElementsByTagName("div");
   if(oEle.length!=0)
   {
    var i;
    for(i=0;i     {
     var subObj = oEle.item(i);
     if(subObj.parentNode==obj)
     {
      subObj.style.display="block";
     }
    }
   }
   o.setAttribute("src",treeview.icon["open"]);
   obj.setAttribute("roll",1);
  }  
  else if(obj.getAttribute("roll")==1)
  {
   var oEle = obj.getElementsByTagName("div");
   if(oEle.length!=0)
   {
    var i;
    for(i=0;i     {
     var subObj = oEle.item(i);
     if(subObj.parentNode==obj)
     { 
      if(subObj.getAttribute("roll")==1)
      {
       this.hideDiv(subObj);
      }
      subObj.style.display="none"; 
     } 
    }
   }
   o.setAttribute("src",treeview.icon["close"]);
   obj.setAttribute("roll",0);
  }  
 }
 
 this.hideDiv=function(o)
 {
  var oEle = o.getElementsByTagName("div");
  if(oEle.length!=0)
  {
   var i;
   for(i=0;i    {
    var subObj = oEle.item(i);
    if(subObj.parentNode==o)
    { 
     if(subObj.getAttribute("roll")==1)
     {
      this.hideDiv(subObj);
     }
     subObj.style.display="none"; 
    } 
   }
  }
  o.childNodes.item(0).setAttribute("src",treeview.icon["close"]);
  o.setAttribute("roll",0);
 }
 
 this.hidemenu=function()
 {
  menu.style.display="none";
 }
 
 this.childNodeNum=function(o)
 {
  var oEle = o.getElementsByTagName("DIV");
  return oEle.length;
 }
 
}

5。showTree.jsp

java 代码
  1.   
  2.   
  3.      
  4.        
  5.     "Content-Type" content="text/html; charset=utf-8">   
  6.     "stylesheet" type="text/css" href="/Doc/css/panel.css">   
  7.     <script type=< span="">"text/javascript" src="/Doc/js/treeview.js" charset="utf-8"></script>   
  8.     <script type=< span="">"text/javascript" src="/Doc/js/ajax.js" charset="utf-8"></script>   
  9.      
  10.       
  11.   "treeview.hidemenu()" class="blue">   
  12.  <script language=< span="">"javascript">   
  13.     var renamefolder = "重命名文件夹";   
  14.     var makefolder = "新建文件夹";   
  15.     var delfolder = "删除文件夹";   
  16.     req.getxmldata(<%= userid %>);   
  17.        
  18.  </script>   
  19.      
  20.   

 

//晕啊,这什么编辑器啊,上传个文件都有bug!!!删除多余的删了n年也没反应!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一些参考代码来实现这个功能。首先,你需要在Spring Boot项目中添加MongoDB的依赖,可以在pom.xml中添加以下代码: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> ``` 然后,你需要创建一个Book类,用于表示书籍信息,可以在src/main/java目录下创建一个Book.java文件,代码如下: ```java package com.example.demo; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; @Document(collection = "books") public class Book { @Id private String id; private String name; private String author; private String description; // getters and setters } ``` 接下来,你需要创建一个BookRepository类,用于操作MongoDB数据库中的books集合,可以在src/main/java目录下创建一个BookRepository.java文件,代码如下: ```java package com.example.demo; import java.util.List; import org.springframework.data.mongodb.repository.MongoRepository; public interface BookRepository extends MongoRepository<Book, String> { List<Book> findByNameContainingIgnoreCase(String name); List<Book> findByAuthorContainingIgnoreCase(String author); } ``` 在这个类中,我们使用了MongoRepository接口提供的一些方法,如findByNameContainingIgnoreCase和findByAuthorContainingIgnoreCase,用于模糊搜索书名和作者名。 现在,你可以创建一个BookController类,用于处理前端Ajax请求,可以在src/main/java目录下创建一个BookController.java文件,代码如下: ```java package com.example.demo; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class BookController { @Autowired private BookRepository bookRepository; @GetMapping("/search") public List<Book> search(@RequestParam("q") String keyword) { List<Book> books = bookRepository.findByNameContainingIgnoreCase(keyword); books.addAll(bookRepository.findByAuthorContainingIgnoreCase(keyword)); return books; } } ``` 在这个类中,我们使用了@GetMapping注解来标记search方法,它接收一个名为q的参数,表示搜索关键词。在方法体中,我们通过BookRepository接口提供的方法来搜索书籍信息,并返回一个Book列表给前端。 最后,你需要在前端页面中编Ajax代码来调用这个接口。可以在src/main/resources/static目录下创建一个index.html文件,代码如下: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>图书搜索</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script> $(function() { $('#search').click(function() { var keyword = $('#keyword').val(); $.get('/search?q=' + keyword, function(data) { var html = ''; $.each(data, function(index, book) { html += '<div>'; html += '<h3>' + book.name + '</h3>'; html += '<p>' + book.author + '</p>'; html += '<p>' + book.description + '</p>'; html += '</div>'; }); $('#results').html(html); }); }); }); </script> </head> <body> <h1>图书搜索</h1> <input type="text" id="keyword" /> <button id="search">搜索</button> <div id="results"></div> </body> </html> ``` 在这个页面中,我们使用了jQuery库来编Ajax代码,当用户点击搜索按钮时,它会发送一个GET请求到/search接口,并将搜索关键词作为参数传递。接着,我们使用each函数遍历返回的Book列表,并将它们以HTML格式显示在页面上。 至此,你就可以在Eclipse中运行这个Spring Boot项目,并在浏览器中访问http://localhost:8080/index.html来搜索图书信息了。同时,你也可以使用Robo3T连接MongoDB数据库,查看books集合中的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值