利用ztree实现树搜索
最近工作中需要利用ztree实现树搜索功能,在网上看了一下别人的*觉得都有点不适合需求,所以根据自己的实际情况进行了改进,经过几次优化,觉得效果还能用:
/**
* 搜索功能3.0
* @type {Element}
*/
var node = document.querySelector('#client_name');
var cpLock = false;
var bower = myBrowser() //判断浏览器类型,在此省略
//实现延迟搜索,如果上次的输入还没有被执行,那么就取消上一次的执行
var timeoutId = null;
function searchNodeLazy(keyword) {
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(function(){
search_keyword(keyword);
}, 500);
}
//实现模糊搜索
function search_keyword(keyword) {
if(keyword === ""){
return;
}
var zTree = $.fn.zTree.getZTreeObj("ztree");
var allNodes = zTree.transformToArray(zTree.getNodes());
zTree.hideNodes(allNodes); //当开始搜索时,先将所有节点隐藏
var nodeList = zTree.getNodesByParamFuzzy('role_name', keyword, 0); //通过关键字模糊搜索
var arr = new Array();
for(var i=0; i<nodeList.length; i++){
arr = $.merge(arr,nodeList[i].getPath()); //找出所有符合要求的叶子节点的路径
}
zTree.showNodes($.unique(arr)); //显示所有要求的节点及其路径节点
zTree.expandAll(true); //展开路径
}
//监听搜索框compositionstart、compositionend事件
node.addEventListener('compositionstart', function(){
cpLock = true;
})
node.addEventListener('compositionend', function(){
cpLock = false;
if(!cpLock){
if (bower=="Chrome" || bower=="Safari") {
dis_name.val($(this).val());
searchNodeLazy(dis_name.val());
}
};
});
node.addEventListener('input', function(){
if(!cpLock){
dis_name.val($(this).val());
searchNodeLazy(dis_name.val());
}
});
效果:大约有46000个测试数据,执行一次搜索话费的时间在1s到1.5s之间,基本上可以满足实际需求
缺点:1、由于没有查询按钮,我们只能通过compositionstart、compositionend事件来判断用户是否输入完成,这有时会造成连续搜索,致使网页卡顿,即使我们设计了一定的延迟搜索,也不能完全解决这个问题。
2、这个搜索只适用于单选场景。
在某些情况下,我们选择全部节点后,又需要排除某些节点,这是我们需要另一种搜索方案。
/**
* 搜索功能2.0
* @type {Element}
*/
var node = document.querySelector('#client_name');
var cpLock = false;
var bower = myBrowser()
//根据传过来的子节点,搜索到最终的父节点(根节点下的)
function getRootParent(node) {
if (node.level < 2) {
return node;
} else {
var rootParent = getRootParent(node.getParentNode());
}
return rootParent;
}
//实现延迟搜索,如果上次的输入还没有被执行,那么就取消上一次的执行
var timeoutId = null;
function searchNodeLazy(keyword) {
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(function(){
search_keyword(keyword);
}, 500);
}
//实现高亮搜索
function search_keyword(keyword) {
if(keyword === ""){
return;
}
var zTree = $.fn.zTree.getZTreeObj("ztree");
var allNodes = zTree.transformToArray(zTree.getNodes());
//关闭上一次查询展开的高亮节点
for(var i=0; i < allNodes.length; i++){
if(allNodes[i].highlight == true) {
allNodes[i].highlight = false;
zTree.expandNode(getRootParent(allNodes[i]), false, true, false); //关闭展开的节点
}
zTree.updateNode(allNodes[i]);
}
//实现模糊搜索
var nodeList = zTree.getNodesByParamFuzzy('role_name', keyword, 0);
var arr = new Array();
for(var i=0; i<nodeList.length; i++){
nodeList[i].highlight = true; // 设置高亮
arr = $.merge(arr,nodeList[i].getPath()); //找到高亮节点的路径
}
var searchNodes = $.unique(arr);
for(var i = 0; i < searchNodes.length; i++){
zTree.expandNode(zTree.getNodes()[0],true); //展开时必须先展开根节点,其余节点才能展开(可能是ztree的BUG)
zTree.expandNode(searchNodes[i],true);
zTree.updateNode(searchNodes[i]);
}
}
node.addEventListener('compositionstart', function(){
cpLock = true;
})
node.addEventListener('compositionend', function(){
cpLock = false;
if(!cpLock){
if (bower=="Chrome" || bower=="Safari") {
dis_name.val($(this).val());
searchNodeLazy(dis_name.val());
}
};
});
node.addEventListener('input', function(){
if(!cpLock){
dis_name.val($(this).val());
searchNodeLazy(dis_name.val());
}
});
这个搜索和上个不同之处在于,搜索之后将不会隐藏不包含关键字的内容,只是将含有关键字的节点设置为高亮并且将其路径展开而已。