Skip to content

Latest commit

History

27 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

项目概述:

zTree 是一个依靠 jQuery 实现的多功能 “树插件”
本项目为 zTree 添加模糊搜索功能
当前功能已被 zTree 收录,可查看官方 demo演示

1. 在搜索框中输入关键字,希望实现的效果:

a). 树形图隐藏所有不匹配的节点

b). 节点名称中匹配部分高亮

2. 慢速演示:

ztree_demo

3. 完整代码和详细注释如下:

a). html部分

<!-- fuzzysearch.html --><!DOCTYPE html><html><head><metacharset="UTF-8"><linkrel="stylesheet" type="text/css" href="css/metro.css" /><styletype="text/css">ul.ztree {
margin-top:10px;
border:1px solid #617775;
width:600px;
height:450px;
overflow-y: scroll;
overflow-x: auto;
}
div.zTreeDemoBackground {
width:600px;
height:450px;
text-align: left;
}
span.search_highlight {
color: whitesmoke;
background-color: darkred; }
</style><!-- 定义了一些模拟数据的js文件dataset.js --><scripttype="text/javascript" src="js/dataset.js"></script><!-- 引入jquery --><scripttype="text/javascript" src="js/jquery-1.4.4.min.js"></script><!-- 引入ztree插件 --><scripttype="text/javascript" src="js/jquery.ztree.all.min.js"></script><!-- 引入ztree插件扩展功能 --><scripttype="text/javascript" src="js/jquery.ztree.exhide.min.js"></script><!-- 引入自定义方法 --><scripttype="text/javascript" src="js/fuzzysearch.js"></script></head><body><divstyle="width: 600px"><inputid="keyword" type="search" placeHolder="搜索关键字"/></div><divclass="content_wrap"><divclass="zTreeDemoBackground left"><ulid="book" class="ztree"></ul></div></div><br/><div><small>*参照亚马逊中文网图书板块的结构创建了模拟数据</small></div><scripttype="text/javascript">//此高亮用于整个节点/* function setHighlight(treeId, treeNode) { return (treeNode.highlight) ? {"font-weight":"bold", "background-color": "#ddd"} : {"font-weight":"normal", "background-color": "transparent"};	} *///ztree配置varsetting={check: {enable: true//checkbox},view: {// 使用ztree自定义高亮时,一定要设置fontCss,setHighlight是自定义高亮方法//fontCss: setHighlight,nameIsHTML: true,//允许name支持html selectedMulti: false},edit: {enable: false,editNameSelectAll: false},data: {simpleData: {enable: true}}};$(document).ready(function(){//从服务器读取数据并初始化树形图//loadDataFromServer(urlStr); //本例直接从模拟数据dataset.js读取loadDataFromLocal();//从本地dataset.js文件读取模拟数据并初始化树形图});/** * 通过ajax方法从服务器获取数据并初始化树形图 */functionloadDataFromServer(urlStr){$.ajax({type: "get",dataType: "json",url: urlStr,//服务请求地址 success: function(data){initThisZtree(data);//传入数据,初始化ztreefuzzySearch('book','#keyword',null,true);//初始化模糊搜索方法}});}/** * 从本地js/dataset.js文件读取模拟数据并初始化树形图 */functionloadDataFromLocal(){//此处的树节点数据mockData是在本地js/dataSet.js中预先定义的模拟数据initThisZtree(mockData);//传入数据,初始化ztree// zTreeId ztree对象的id,不需要#// searchField 输入框选择器// isHighLight 是否高亮,默认高亮,传入false禁用// isExpand 是否展开,默认合拢,传入true展开fuzzySearch('book','#keyword',null,true);//初始化模糊搜索方法}/** * 初始化ztree *  * @param {Object} data */functioninitThisZtree(data){//初始化ztree三个参数分别是(jQuery对象,ztree设置,树节点数据)vartreeObj=$.fn.zTree.init($("#book"),setting,data);treeObj.expandAll(true);}</script></body></html>

b). js部分

/** *  * @param zTreeId ztree对象的id,不需要# * @param searchField 输入框选择器 * @param isHighLight 是否高亮,默认高亮,传入false禁用 * @param isExpand 是否展开,默认合拢,传入true展开 * @returns */functionfuzzySearch(zTreeId,searchField,isHighLight,isExpand){varzTreeObj=$.fn.zTree.getZTreeObj(zTreeId);//获取树对象if(!zTreeObj){alter("获取树对象失败");}varnameKey=zTreeObj.setting.data.key.name;//获取name属性的keyisHighLight=isHighLight===false?false:true;//除直接输入false的情况外,都默认为高亮isExpand=isExpand?true:false;zTreeObj.setting.view.nameIsHTML=isHighLight;//允许在节点名称中使用html,用于处理高亮varmetaChar='[\\[\\]\\\\\^\\$\\.\\|\\?\\*\\+\\(\\)]';//js正则表达式元字符集varrexMeta=newRegExp(metaChar,'gi');//匹配元字符的正则表达式// 过滤ztree显示数据functionztreeFilter(zTreeObj,_keywords,callBackFunc){if(!_keywords){_keywords='';//如果为空,赋值空字符串}// 查找符合条件的叶子节点functionfilterFunc(node){if(node&&node.oldname&&node.oldname.length>0){node[nameKey]=node.oldname;//如果存在原始名称则恢复原始名称}//node.highlight = false; //取消高亮zTreeObj.updateNode(node);//更新节点让之前对节点所做的修改生效if(_keywords.length==0){//如果关键字为空,返回true,表示每个节点都显示zTreeObj.showNode(node);zTreeObj.expandNode(node,isExpand);//关键字为空时是否展开节点returntrue;}//节点名称和关键字都用toLowerCase()做小写处理if(node[nameKey]&&node[nameKey].toLowerCase().indexOf(_keywords.toLowerCase())!=-1){if(isHighLight){//如果高亮,对文字进行高亮处理//创建一个新变量newKeywords,不影响_keywords在下一个节点使用//对_keywords中的元字符进行处理,否则无法在replace中使用RegExpvarnewKeywords=_keywords.replace(rexMeta,function(matchStr){//对元字符做转义处理return'\\'+matchStr;});node.oldname=node[nameKey];//缓存原有名称用于恢复//为处理过元字符的_keywords创建正则表达式,全局且不分大小写varrexGlobal=newRegExp(newKeywords,'gi');//'g'代表全局匹配,'i'代表不区分大小写//无法直接使用replace(/substr/g,replacement)方法,所以使用RegExpnode[nameKey]=node.oldname.replace(rexGlobal,function(originalText){//将所有匹配的子串加上高亮效果varhighLightText='<span style="color: whitesmoke;background-color: darkred;">'+originalText+'</span>';returnhighLightText;});//================================================////node.highlight用于高亮整个节点//配合setHighlight方法和setting中view属性的fontCss//因为有了关键字高亮处理,所以不再进行相关设置//node.highlight = true; //================================================//zTreeObj.updateNode(node);//update让更名和高亮生效}zTreeObj.showNode(node);//显示符合条件的节点returntrue;//带有关键字的节点不隐藏}zTreeObj.hideNode(node);// 隐藏不符合要求的节点returnfalse;//不符合返回false}varnodesShow=zTreeObj.getNodesByFilter(filterFunc);//获取匹配关键字的节点processShowNodes(nodesShow,_keywords);//对获取的节点进行二次处理}/** * 对符合条件的节点做二次处理 */functionprocessShowNodes(nodesShow,_keywords){if(nodesShow&&nodesShow.length>0){//关键字不为空时对关键字节点的祖先节点进行二次处理if(_keywords.length>0){$.each(nodesShow,function(n,obj){varpathOfOne=obj.getPath();//向上追溯,获取节点的所有祖先节点(包括自己)if(pathOfOne&&pathOfOne.length>0){//对path中的每个节点进行操作// i < pathOfOne.length-1, 对节点本身不再操作for(vari=0;i<pathOfOne.length-1;i++){zTreeObj.showNode(pathOfOne[i]);//显示节点zTreeObj.expandNode(pathOfOne[i],true);//展开节点}}});}else{//关键字为空则显示所有节点, 此时展开根节点varrootNodes=zTreeObj.getNodesByParam('level','0');//获得所有根节点$.each(rootNodes,function(n,obj){zTreeObj.expandNode(obj,true);//展开所有根节点});}}}//监听关键字input输入框文字变化事件$(searchField).bind('input propertychange',function(){var_keywords=$(this).val();searchNodeLazy(_keywords);//调用延时处理});vartimeoutId=null;// 有输入后定时执行一次,如果上次的输入还没有被执行,那么就取消上一次的执行functionsearchNodeLazy(_keywords){if(timeoutId){//如果不为空,结束任务clearTimeout(timeoutId);}timeoutId=setTimeout(function(){ztreeFilter(zTreeObj,_keywords);//延时执行筛选方法$(searchField).focus();//输入框重新获取焦点},500);}}

c). 模拟数据部分

/*dataset.js*/var mockData = [{"name": "图书",
"pId": "",
"id": "0"}, {"name": "其他1",
"pId": "",
"id": "1"},{"name": "其他2",
"pId": "",
"id": "2"},{"name": "其他3",
"pId": "",
"id": "3"},
{
"name": "测试js正则元字符:[]\\^$.|?*+()",
"pId": "0",
"id": "06"
},{
"name": "测试其他字符:{}<>'\"~`!@#%&-;:/,",
"pId": "0",
"id": "07"
},{
"name": "测试大小写同节点: 大写ABDEFGHINQRT,小写abdefghinqrt",
"pId": "0",
"id": "08"
},{
"name": "测试大写ABDEFGHINQRT",
"pId": "0",
"id": "09"
},{
"name": "测试小写abdefghinqrt",
"pId": "0",
"id": "10"
},{
"name": "文学",
"pId": "0",
"id": "00"
}, {
"name": "历史",
"pId": "0",
"id": "01"
}, {
"name": "法律",
"pId": "0",
"id": "02"
}, {
"name": "辞典与工具书",
"pId": "0",
"id": "03"
}, {
"name": "科学与自然",
"pId": "0",
"id": "04"
},{
"name": "自然科学总论",
"pId": "04",
"id": "040"
},{
"name": "数学",
"pId": "04",
"id": "041"
},{
"name": "物理",
"pId": "04",
"id": "042"
},{
"name": "天文学 地球科学",
"pId": "04",
"id": "043"
}, {
"name": "计算机与互联网",
"pId": "0",
"id": "05"
}, {
"name": "编程与开发",
"pId": "05",
"id": "050"
}, {
"name": "编程语言与工具",
"pId": "050",
"id": "0500"
}, {
"name": "C & C++",
"pId": "0500",
"id": "05000"
},{
"name": "JAVA",
"pId": "0500",
"id": "05001"
},{
"name": "Python",
"pId": "0500",
"id": "05002"
},{
"name": "Python编程 从入门到实践",
"pId": "05002",
"id": "050020"
},{
"name": "Python编程快速上手 让繁琐工作自动化",
"pId": "05002",
"id": "050021"
}, {
"name": "算法与数据结构",
"pId": "050",
"id": "0501"
}, {
"name": "编译原理和编译器",
"pId": "050",
"id": "0502"
}, {
"name": "操作系统",
"pId": "05",
"id": "051"
}, {
"name": "数据库",
"pId": "05",
"id": "052"
}, {
"name": "计算机科学理论",
"pId": "05",
"id": "053"
}, {
"name": "云计算与大数据",
"pId": "05",
"id": "054"
}]

4.参考资料:

a). ztree根据关键字模糊搜索
b). 我也来实现ztree模糊搜索功能

About

zTree实现树形图模糊搜索

Resources

Stars

51 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages