树状列表组件JSTree的使用

项目里有这样一个需求:要查看系统文件夹里面的所有图片,按目录分门别类放置。
其实说白了就是做一个树状的列表
如下图

而我电脑上的文件组织就和显示的一样:




工作过几年的程序员,应该知道,一旦碰上类似的问题,就先去网上找找,看有没有现有的组件能帮助我们,别一个人在电脑前傻兮兮的自己想。很多问题,我们并不是第一个遇到的,肯定有前辈为我们找到了合适的方法。如果实在找不到组件,那再自己写。即使找不到,但是至少,你得先去找过!
一个优秀的程序员应该学会参考别人的代码。



OK先介绍一个这个组件
全名 JSTree
官网 https://www.jstree.com/
git https://github.com/vakata/jstree
说明文档也在git上


我先来简单介绍一下这个组件吧
下面这个例子的代码如下:

<div id="container"></div>
<script>
$(function() {
  $('#container').jstree({
    'core' : {
      'data' : {
        "url" : "//www.jstree.com/fiddle/?lazy",
        "data" : function (node) {
          return { "id" : node.id };
        }
      }
    }
  });
});
</script>

就上面的代码来说,组件第一次给后台发的请求是www.jstree.com/fiddle/?lazy&id=#
返回的json如下:
[{
  "id":1,"text":"Root node","children":[
    {"id":2,"text":"Child node 1","children":true},
    {"id":3,"text":"Child node 2"}
  ]
}]
看到了吧,id为2的item的children属性是true,这说明什么?说明这个item下面还有文件/文件夹
你点击一下这个item,组件就会再次向后台请求新的数据,请求地址是www.jstree.com/fiddle/?lazy&id=2
返回的结果是
["Child node 3","Child node 4"]
我们看到的是

OK,现在上我写的例子:

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>标题</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">


<script src="js/jquery.min.js"></script>
<script src="js/jstree.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<link rel="stylesheet" href="css/style.min.css" />
<link rel="stylesheet" href="css/bootstrap.min.css" />


</head>
<body>

  
	<div id="container" style="float:left;margin-left: 15%;margin-top: 0.51%;"></div>
	
	<div id="pic"   style="padding-left: 80px;    padding-top: 80px;" >
	   <img id="plant" alt="" src="" style="padding-left: 10%;" > 
	</div>
</body>


<script type="text/javascript">  

	$(function() {


			  $('#container').jstree({
			    'core' : {
			      'data' : {
			        "url" : "http://localhost:8700/ShowPictures/ShowIndex",
			        "data" : function (node) {
			          return { "id" : node.id };
			        }
			      }
			    }
			  });
			  
			  $('#container').on("changed.jstree", function (e, data) {
				    var name=String(data.selected);   //必须得转换成字符串
				//    alert(name);
				    if(name.search("jpg")>1||name.search("png")>1){
				    	$("#plant").attr("src",name);                
				    //	$("#pic").hide();
				    }
				  });
			});
	
	</script>
</html>


OK我们看后台处理逻辑

@WebServlet( urlPatterns = "/ShowIndex")
public class ShowIndexServlet extends HttpServlet {
	
	/**
	 * https://github.com/vakata/jstree
	 */
	private static final long serialVersionUID = -3867365983209162571L;


	
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("utf-8");
		response.setContentType("application/json;charset=utf-8");
		PrintWriter out = response.getWriter();
		String result="";
		String id=request.getParameter("id");
	//	System.out.println("i get id "+id);
	//	public static final String  PLANT_LOCATION="E:\\plant";
	//      public static final String PARENT_LOCATION="E:\\";
		if (id.equals("#")) {
			result=ShowFiles.getChildrenFiles(Config.PLANT_LOCATION);
		}else{
		//	id = new String (id.getBytes("iso-8859-1"), "UTF-8") ; 
			result=ShowFiles.getChildrenFiles(Config.PARENT_LOCATION+id);
		}
		out.write(result);
		out.flush();
		out.close();
	}
}
注意:因为我的目录上有中文,本来是使用id = new String (id.getBytes("iso-8859-1"), "UTF-8") ; 来做转换的,后来发现tomcat路径中文问题直接在server.xml的Connector里加上 URIEncoding="utf-8"即可:
<Connector connectionTimeout="20000" port="8700"  URIEncoding="utf-8"  protocol="HTTP/1.1" redirectPort="8443"/>
加上 URIEncoding="utf-8"后,在代码里就不需要转换了。


下面就是读取某个文件下的文件夹和文件了。
public class ShowFiles {
	public static String getChildrenFiles(String parentPath) {


		JSONArray list = new JSONArray();
		File file = new File(parentPath);
		File[] tempList = file.listFiles();
	//	System.out.println("该目录下对象个数:" + tempList.length);
		String fileName="";
		for (int i = 0; i < tempList.length; i++) {
			JSONObject item = new JSONObject();
			if (tempList[i].isFile()) {
		//		System.out.println("文     件:" + tempList[i]);
		//为什么substring(3) 因为我去掉了盘符
				item.put("id", tempList[i].toString().substring(3));
                //每一个item都有哪些属性?自己去git上看吧
				item.put("icon", "images/icon.png");
				fileName=tempList[i].getName();
				item.put("text", fileName.substring(0,fileName.lastIndexOf(".")));
			}
			if (tempList[i].isDirectory()) {
		//		System.out.println("文     件夹:" + tempList[i]);
				item.put("id", tempList[i].toString().substring(3));
				item.put("text", tempList[i].getName());
				//如果是文件夹 children就是true
				item.put("children", true);
			}
			list.add(item);
		}


	//	System.out.println(list);
		return list.toString();
	}


}
看到上面的代码,大家应该明白了,列表里每个item的id就是这个文件/文件夹的全地址(我去掉了盘符),text(就是在页面上显示的内容)是文件名


那么怎么做的我点击列表里的图片,在右边就显示它呢?
这说白了就是jstree的事件功能么。
			//点击任何一个item就会调用下面的的代码
			$('#container').on("changed.jstree", function (e, data) {
				    var name=String(data.selected);   //必须得转换成字符串
				//    alert(name);
				    if(name.search("jpg")>1||name.search("png")>1){
				    	$("#plant").attr("src",name);                
				    }
				  });
			});
如果item的id里面包含了jpg或者png我就认为它是图片
其实我们刚才说了item有个children属性如果是true就说明是文件夹,反之就是文件
可是我在事件里找不到那个children属性..惭愧...
api如下:大家看看

https://www.jstree.com/api/


项目使用的js/与css如下:

http://pan.baidu.com/s/1jIqaJLc


好的,以下是一个使用 JavaScript 实现的 tree 树形单选组件的示例代码: HTML: ```html <div id="tree"></div> ``` JS: ```javascript // 树形数据 const treeData = [ { id: '1', label: '节点1', children: [ { id: '1-1', label: '节点1-1', children: [ { id: '1-1-1', label: '节点1-1-1' }, { id: '1-1-2', label: '节点1-1-2' } ] }, { id: '1-2', label: '节点1-2' } ] }, { id: '2', label: '节点2' } ] // 递归生成树形节点 function createTreeNode(data) { const ul = document.createElement('ul') for (let i = 0; i < data.length; i++) { const li = document.createElement('li') const label = document.createElement('label') const checkbox = document.createElement('input') checkbox.type = 'checkbox' checkbox.name = 'tree-node' checkbox.value = data[i].id label.appendChild(checkbox) label.appendChild(document.createTextNode(data[i].label)) li.appendChild(label) if (data[i].children && data[i].children.length) { li.appendChild(createTreeNode(data[i].children)) } ul.appendChild(li) } return ul } // 获取选中的节点 function getSelectedNode() { const nodeList = document.getElementsByName('tree-node') for (let i = 0; i < nodeList.length; i++) { if (nodeList[i].checked) { return nodeList[i].value } } return null } // 渲染树形组件 function renderTree() { const tree = document.getElementById('tree') tree.appendChild(createTreeNode(treeData)) tree.addEventListener('click', function (event) { const target = event.target if (target.nodeName === 'INPUT' && target.type === 'checkbox') { const nodeList = document.getElementsByName('tree-node') for (let i = 0; i < nodeList.length; i++) { if (nodeList[i] !== target) { nodeList[i].checked = false } } } }) } renderTree() ``` 这段代码会渲染一个树形节点,并且支持单选功能。每个节点都有一个复选框,选中一个节点时,会取消其他节点的选中状态。你可以根据自己的需求修改代码,实现更加复杂的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值