最近做的任务提了新的需求,把之前做的下拉框里的内容用层级关系呈现出来,虽然后面由于后台参数不足没有实现(做了个假的),但还是好奇尝试一番,以免以后遇到类似的问题。
这里顺带记录一下可搜索下拉框的使用,目前我们这个项目使用的是bootstrap-select插件,用法也很简单,马克一下。
首先去官网拿到插件包,放到项目里,主要引入这两个文件。
<link href="./bootstrap-select-1.13.2/dist/css/bootstrap-select.min.css" rel="stylesheet" />
<script src="./bootstrap-select-1.13.2/dist/js/bootstrap-select.min.js"></script>
注意:bootstrap-select依赖于bootstrap,而bootstrap依赖于 jQuery,
所以在引入这两个文件前,记得把jquery和bootstrap的主要文件依次引入一下,当然如果你会使用requireJs那就更好了
写好这步以后只需要给select标签加上selectpicker类就大功告成了。
bootstrap-select 配有不同的扩展功能(多选、可搜索、分组),可以根据我们自己的需求去给select添加属性。
下面说几个比较常用的写法:
属性
- multiple: 多选属性
- data-live-search=”true” 可搜索属性
- data-max-options=”3” 多选时可选择的最大个数
- data-selected-text-format=”count > 3” 超过三个时不显示选中内容,显示选中个数
- data-size=”6” 下拉框可视个数,超过时显示滚动条
函数
$('.selectpicker').selectpicker('val', str); // 初始化单选
$('.selectpicker').selectpicker('val', arr); // 初始化多选
$('.selectpicker').selectpicker('selectAll'); // 全选
$('.selectpicker').selectpicker('deselectAll'); // 反选
$('.selectpicker').selectpicker('refresh'); // 刷新UI(常用于添加、删除option,需要更新状态)
$('.selectpicker').selectpicker('render'); // 强制更新UI,异步加载数据必备啊!!!
有兴趣的同学可以去看官网提供的文档。
废话不多说,毕竟本文的重点还是JS 生成树状结构。
首先我们要拿到一组数据,作为整棵树的基本数据。
var aTree = [
{"id": "1", "name": "动物", "pid": "0"},
{"id": "2", "name": "鸟类", "pid": "5"},
{"id": "3", "name": "无脊椎动物", "pid": "1"},
{"id": "4", "name": "哺乳动物", "pid": "5"},
{"id": "5", "name": "脊椎动物", "pid": "1"},
{"id": "6", "name": "喜鹊", "pid": "2"},
{"id": "7", "name": "蚯蚓", "pid": "3"}
];
遇到这种问题一般我们都会想到使用函数递归调用,但是怎么开始呢?假如现在需要获得第一级菜单,我们也许会写出下面的代码。
var aParent = [];
for(var i in aTree){
if (aTree[i].pid == '0') {
aParent.push(aTree[i]);
}
}
很容易发现我们可以用相同的写法获得每一个有子级的父级数据,封装一下就是一个函数。
function getParent(id, aTree) {
var aParent = [];
for (var i in aTree) {
if (aTree[i].pid == id) {
aParent.push(aTree[i]);
}
}
return aParent;
}
接下来我们把已经获得的顶级菜单写入HTML看下效果
var topMenu = getParent(0, aTree);
var menu = '';
for (var i in topMenu) {
menu += '<a href="#">' + topMenu[i].name + '</a>';
}
$('body').append(menu);
看起来有点效果但是差点什么的感觉,接下来我们把上面的代码整合一下,开始递归调用。
var menu = '';
function makeTree(id, aTree) {
var topMenu = getParent(id, aTree);
if (topMenu.length > 0) {
for (var i in topMenu) {
menu += '<a href="#">' + topMenu[i].name + '</a>';
menu += '<ul>' // 为了区分层次,我们给每一个子级都包上一层ul
makeTree(topMenu[i].id, aTree);
menu += '</ul>'
}
}
}
makeTree(0, aTree);
$('body').append(menu);
成效如下:
除了样式丑点,其它没毛病。接下来给它做点优化,让它看起来像个正经菜单。
恩,还是蛮有意思的。