前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简单的树形菜单如何写

简单的树形菜单如何写

作者头像
tianyawhl
发布2019-10-16 11:01:39
2.2K0
发布2019-10-16 11:01:39
举报
文章被收录于专栏:前端之攻略前端之攻略

查看树形菜单

业务需求

数据结构中含有图片、名称、children的树形结构,需要展示出每一级的图片名称和图片,找了些树形图的插件,都没有展示大的图片的,一般都是小图标,就自己试着写一个包含图的简单的插件。

树形图的结构

代码语言:javascript
复制
<ul>
    <li class="tree-item">
        <span class="icon glyphicon glyphicon-list-alt"></span>
        <a>
            <div class="item-name">name1</div>
        </a>
        <ul>
            <li class="tree-item">
                <span class="icon glyphicon glyphicon-list-alt"></span>
                <a>
                    <div class="item-name">name2</div>
                </a>
            </li>
        </ul>
    </li>
</ul>

主要是用ul和li展示,竖线是用ul的before伪元素写的样式,短横线是li的before伪元素写的样式,要解决的问题是竖线和横线的位置,LI中含有图片和不含有图片LI的class不同,同时li内部的ul的class 也不同,因为含有图片和不含图片设置的样式不一样。整个HTML结构采用递归的方式。

事件交互

初始状态是全部展开,点击展开的图标(-)会隐藏同级的UL元素,并改变图标为(+)

代码语言:javascript
复制
$("#tree-box").on("click", ".icon", function() {
    $(this).siblings("ul").toggle();
    if ($(this).hasClass("glyphicon-minus")) {
        $(this).removeClass("glyphicon-minus").addClass("glyphicon-plus")
    } else if ($(this).hasClass("glyphicon-plus")) {
        $(this).removeClass("glyphicon-plus").addClass("glyphicon-minus")
    }
})

如果数据结构是含有PID的,需要先转换成children的数据结构

代码语言:javascript
复制
   var json = [
       { id: 1, pid: 0, text: '1(XX公司)' },
       { id: 2, pid: 4, text: '2.1.1(开发部a-1组)' },
       { id: 3, pid: 0, text: '2(开发部)' },
       { id: 4, pid: 3, text: '2.1(开发部a)' },
       { id: 5, pid: 0, text: '3(人事部)' },
       { id: 6, pid: 5, text: '3.1(人事部A)' },
       { id: 7, pid: 0, text: '4(设计部)' },
       { id: 8, pid: 7, text: '4.1(设计部A)' },
       { id: 9, pid: 4, text: '2.1.2(开发部a-2组)' },
       { id: 11, pid: 2, text: '2.1.1.1(开发部a-1组>1小组)' },
       { id: 12, pid: 2, text: '2.1.1.2(开发部a-1组>2小组)' },
       { id: 13, pid: 5, text: '3.2(人事部A)' },
       { id: 19, pid: 5, text: '3.3(人事部B)' }
   ];

   function translateData(data, idStr, pidStr, chindrenStr) {
       var result = [],
           temp = {},
           id = idStr,
           pid = pidStr,
           children = chindrenStr,
           i = 0,
           j = 0,
           len = data.length;
       // 重新把数组中的对象重新放到一个新的对象中,新的对象是以id 的值为键
       for (; i < len; i++) {
           // 建立temp对象,由于对象是引用类型,修改temp或者data都会引起另一方改变
           temp[data[i][id]] = data[i];
           // temp[a[i][id]] = JSON.parse(JSON.stringify(data[i])); 这种情况data和temp是独立的
       }
       // aVal 存储数组中的对象,获取新对象中key为pid 的对象,如果存在	
       for (; j < len; j++) {
           var dataVal = data[j],
               tempObj = temp[dataVal[pid]];

           if (tempObj) {
               // 如果	tempObj[children]不存在,把tempObj[children]设为数组	
               !tempObj[children] && (tempObj[children] = []);
               tempObj[children].push(dataVal);
           } else {
               // 如果不存在就把dataVal放到结果中		
               result.push(dataVal);
           }
       }
       console.log(data)
       return result;
   }

   document.getElementById("content").innerHTML = JSON.stringify(translateData(json, 'id', 'pid', 'chindren'), null, 2)

完整的代码

代码语言:javascript
复制
    <style type="text/css">
    * {
        padding: 0;
        margin: 0;
    }

    #box {
        margin: 20px;
    }

    .item-group {
        list-style: none;
        margin-left: 20px;
        position: relative;
    }

    .item-group:before {
        content: "";
        display: inline-block;
        position: absolute;
        top: -10px;
        bottom: 15px;
        left: 0;
        border-left: 1px solid #67b2dd;
        z-index: 10;
    }

    .item-group-innerpic {
        list-style: none;
        margin-left: 20px;
        position: relative;
    }

    .item-group-innerpic:before {
        content: "";
        display: inline-block;
        position: absolute;
        top: -48px;
        bottom: 15px;
        left: 0;
        border-left: 1px solid #67b2dd;
        z-index: 10;
    }

    .tree-item {
        position: relative;
        line-height: 30px;
    }

    .tree-item:before {
        display: inline-block;
        content: "";
        position: absolute;
        top: 14px;
        width: 18px;
        height: 0;
        border-top: 1px dotted #67b2dd;
    }

    .tree-item1 {
        position: relative;
        line-height: 30px;
    }

    .tree-item1:before {
        display: inline-block;
        content: "";
        position: absolute;
        top: 48px;
        width: 18px;
        height: 0;
        border-top: 1px dotted #67b2dd;
    }

    .item-group li span {
        margin-left: 20px;
        color: #0994ce;
        margin-right: -15px;
    }

    .item-group li a {
        margin-left: 20px;
		display:inline-block;
    }

    .item-group li img {
	    width:100px;
        height: 100px;
		margin-right:10px;
    }

    .item-group li .item-name {
        display: inline-block
    }
    </style>
代码语言:javascript
复制
    <div id="tree-box">
    </div>
    <script src="../js/jQuery-2.1.4.min.js"></script>
    <script>
    var data = [{
            title: 'biaoti1',
            img: '../imgs/green.png',
            children: [{
                    title: 'biaoti1-1',
                    img: '../imgs/1.jpg',
                    children: [{
                        title: 'biaoti1-1-1'
                    }, ]
                },
                {
                    title: 'biaoti1-2',
                    children: [{
                            title: 'biaoti1-2-1',
                            children: [{
                                    title: 'biaoti1-2-1-1'
                                },
                                {
                                    title: 'biaoti1-2-1-2',
                                    children: [{
                                            title: 'biaoti1-2-1-1-1'
                                        },
                                        {
                                            title: 'biaoti1-2-1-1-2'
                                        }
                                    ]
                                }
                            ]
                        },
                        {
                            title: 'biaoti1-2-2'
                        }
                    ]
                },
                {
                    title: 'biaoti1-3'
                }
            ]
        },
        {
            title: 'biaoti2',
            children: [{
                    title: 'biaoti2-1'
                },
                {
                    title: 'biaoti2-2'
                }
            ]
        },
        {
            title: 'biaoti3',
            children: [{
                    title: 'biaoti3-1'
                },
                {
                    title: 'biaoti3-2'
                }
            ]
        },
        {
            title: 'biaoti4'
        }
    ];
    var width = 50;
    var ulClass = "item-group"
    //封装函数,方便调用
    function render(arr, ulClass) {
        //设置HTML为ul标签对的前半部分,用以将以下内容包括在ul中
        var html = '<ul class="' + ulClass + '">';
        //设置循环,遍历数组中的每一项,最长不超过数组的长度,依次遍历
        for (var i = 0; i < arr.length; i++) {
            //设置第一级ul中的li结构  <li><span>每个标题</span></li>
            // console.log(arr[i])
            //判断数组arr【i】的下方是否还有结构

            if (!arr[i].children) {
                if (arr[i].img) {
                    html += '<li class="tree-item1"><span class="icon glyphicon glyphicon-list-alt"></span><a><img src="' + arr[i].img + '" alt="" class="pic"/><div class="item-name">' + arr[i].title + '</div></a>';
                } else {
                    html += '<li class="tree-item"><span class="icon glyphicon glyphicon-list-alt"></span><a><div class="item-name">' + arr[i].title + '</div></a>';
                }
            } else {
                if (arr[i].img) {
                    html += '<li class="tree-item1"><span class="icon glyphicon glyphicon-minus"></span><a><img src="' + arr[i].img + '" alt="" class="pic"/><div class="item-name">' + arr[i].title + '</div></a>';
                    html += render(arr[i].children, "item-group-innerpic")
                } else {
                    html += '<li class="tree-item"><span class="icon glyphicon glyphicon-minus"></span><a><div class="item-name">' + arr[i].title + '</div></a>';
                    html += render(arr[i].children, "item-group")
                }
                //如果有,就增加结构

            }
            //设置第一级li的后标签
            html += '</li>'
        }
        //设置第一级ul的后标签
        html += '</ul>'
        return html;
    }
    //调用函数,传参数组data,将其赋值给第一级ul的父级结构box,生成动态菜单
	var treebox = document.getElementById("tree-box")
    treebox.innerHTML = render(data, ulClass);

    $("#tree-box").on("click", ".icon", function() {
        $(this).siblings("ul").toggle();
        if ($(this).hasClass("glyphicon-minus")) {
            $(this).removeClass("glyphicon-minus").addClass("glyphicon-plus")
        } else if ($(this).hasClass("glyphicon-plus")) {
            $(this).removeClass("glyphicon-plus").addClass("glyphicon-minus")
        }
        //console.log(this)
    })
    </script>

© 著作权归作者所有

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 查看树形菜单
  • 业务需求
  • 树形图的结构
  • 事件交互
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档