JS实现树形选择器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS实现树形选择器相关的知识,希望对你有一定的参考价值。
实现类似于百度文库的,分类选择,但是需要能多选,还要是弹出层。
如果合适,肯定追加
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>制作树形菜单</title>
<style type="text/css">
div/*隐藏层*/
display:none;
a /*文字链接的背影样式*/
font-size:13px;
color: #ffffff;
text-decoration: none;
background-color:#669933;
width:100px;
line-height:25px;
text-align:center;
display: block;
border-right:1px solid #ffffff;
border-bottom:1px solid #ffffff;
a:hover
/*鼠标在文字链接上时的文字背景样式*/
font-size:13px;
color: #ffffff;
background-color:#ee9d01;
width:100px;
text-align:center;
display: block;
</style>
<script type="text/javascript">
function show(d)
document.getElementById(d).style.display='block'; //显示层
function hide(d)
document.getElementById(d).style.display='none'; //隐藏层
</script>
</head>
<body>
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td><a href="#" onmousemove="show(1)" onmouseout="hide(1)">手机数码</a></td>
<td><a href="#" onmousemove="show(2)" onmouseout="hide(2)">淘宝集市</a></td>
<td><a href="#" onmousemove="show(3)" onmouseout="hide(3)">品牌商城</a></td>
</tr>
<tr>
<td>
<div id="1" >
<a href="#">手机数码1</a>
<a href="#">手机数码2</a>
<a href="#">手机数码3</a>
</div>
</td>
<td>
<div id="2" >
<a href="#">淘宝集市1</a>
<a href="#">淘宝集市2</a>
<a href="#">淘宝集市3</a>
</div>
</td>
<td>
<div id="3" >
<a href="#">品牌商城1</a>
<a href="#">品牌商城2</a>
<a href="#">品牌商城3</a>
</div>
</td>
</tr>
</table>
</body>
</html>追问
看问题补充
追答没那么多时间跟你折腾了,祝你好运!
JS数组递归——构建 element 级联选择器树形数据
JS数组递归——构建 element 级联选择器树形数据
通常,我们前端在开发管理后台的时候,会选择 vue+element
这样的技术栈去实现。但我们后端给的数据格式通常并不符合 element
的参数数据要求。比如,级联选择器 cascader
的参数数据格式如下:
[
"label": "第一级",
"value": 2,
"children": [
"label": "第二级",
"value": 4,
"children": [
"label": "第三级",
"value": 13
,
"label": "测试3",
"value": 14
]
]
,
"label": "2",
"value": 3,
"children": [
"label": "4",
"value": 5
]
,
"label": "测试分类2",
"value": 11,
"children": [
"label": "测试分类0",
"value": 12,
"children": [
"label": "测试分类3",
"value": 15
]
]
]
而我们后端在输出接口的时候,是极少采用这种数据格式的。比如,一般叫 id
|name
|child
这样的字段名。
我们知道,cascader
是支持这样的别名参数设计的,因此我们使用时也没什么问题。
但是我今天遇到的一个状况是,后端直接给出了一个一维数组,换句话说,这位兄弟是直接查了一下数据表,把所有的数据通过一个数组直接给我返回了。而至于我怎么使用这个数据,他就不考虑了,因为他还有其他业务需要开发。
后端返回的数据格式如下:
[
"catid": 2,
"parentId": 0,
"catname": "第一级",
,
"catid": 3,
"parentId": 0,
"catname": "2",
,
"catid": 4,
"parentId": 2,
"catname": "第二级",
,
"catid": 5,
"parentId": 3,
"catname": "4",
,
"catid": 12,
"parentId": 11,
"catname": "测试分类0",
,
"catid": 11,
"parentId": 0,
"catname": "测试分类2",
,
"catid": 13,
"parentId": 4,
"catname": "第三级",
,
"catid": 14,
"parentId": 4,
"catname": "测试3",
,
"catid": 15,
"parentId": 12,
"catname": "测试分类3",
]
嗯,理解。不就是个简单的递归嘛!我一会儿就写好了。但我担心后面其他地方还有这样类似的接口输出,那我总是写递归不就很麻烦了吗?因此,将此方法抽离,并加了一些扩展,最终方法代码如下:
export const makeElementTree = (params) =>
// 将参数拿出来,不喜欢 params.xxx 的调用方式
const pid, list, pidFiled, labelFiled, valueFiled = params
// 构建一个内部函数,用于实现递归
const makeTree = (pid, arr) =>
const res = []
arr.forEach(i =>
if (i[pidFiled] === pid)
// 自己调用自己,递归查归属于自己的 children
const children = makeTree(i[valueFiled], list)
// 将原有的数据按照 element 的格式进行重构
const obj =
label: i[labelFiled],
value: i[valueFiled]
// 如果有 children 则插入 obj 中
if (children.length)
obj.children = children
res.push(obj)
)
return res
return makeTree(pid, list)
在业务代码中,我们首先引入我们的方法,然后传进去参数就可以啦,如下演示:
const treeCats = makeElementTree(
pid: 0, // 顶级分类的 pid 为 0
list: data, // 将原始数组参数穿进去
pidFiled: 'parentId', // 在数组对象中,pid 字段名为 parentId
labelFiled: 'catname',// 我们想要的 label 字段名为 catname
valueFiled: 'catid' // 我们想要的 value 字段名为 catid
)
console.log(treeCats)
通过简单的配置参数,就可以直接获得我们想要的数据格式了。
python 的实现
下面这段是我以前写 python 的时候,实现过的一个类似的递归代码,还是 python 简洁啊!
def makeTree(pid, arr):
res = []
for i in arr:
if i['pid'] == pid:
rep = makeTree(i['id'], arr)
if len(rep) != 0:
i['children'] = rep
res.append(i)
return res
res = makeTree(0, sourceList)
复习了一下递归,还是很简单的嘛!
最后,在编程中,慎用递归!!!
本文由 FungLeo 原创,允许转载,但转载必须保留首发链接。
以上是关于JS实现树形选择器的主要内容,如果未能解决你的问题,请参考以下文章