Business needs
The data structure contains the tree structure of picture, name and children. It needs to show the picture name and picture of each level. After finding some plug-ins of tree chart, they don't show large pictures. Generally, they are small icons, so they try to write a simple plug-in with pictures.
Structure of tree graph
<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>
It is mainly displayed in ul and Li. The vertical line is written in the style of ul's before pseudo element, and the short horizontal line is written in the style of Li's before pseudo element. The problem to be solved is the position of the vertical line and the horizontal line. The class with pictures in Li is different from the class without pictures. At the same time, the class of ul in Li is different, because the style with pictures is different from that without pictures. The whole HTML structure is recursive.
Event interaction
The initial state is to expand all. Clicking the expand icon (-) will hide the UL element of the same level and change the icon to (+)
$("#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") } })
If the data structure contains PID, it needs to be converted into children's data structure first
var json = [ { id: 1, pid: 0, text: '1(XX company)' }, { id: 2, pid: 4, text: '2.1.1(Development Department a-1 group)' }, { id: 3, pid: 0, text: '2(Development Department)' }, { id: 4, pid: 3, text: '2.1(Development Department a)' }, { id: 5, pid: 0, text: '3(Ministry of Personnel)' }, { id: 6, pid: 5, text: '3.1(Ministry of Personnel A)' }, { id: 7, pid: 0, text: '4(Design Department)' }, { id: 8, pid: 7, text: '4.1(Design Department A)' }, { id: 9, pid: 4, text: '2.1.2(Development Department a-2 group)' }, { id: 11, pid: 2, text: '2.1.1.1(Development Department a-1 group>1 group)' }, { id: 12, pid: 2, text: '2.1.1.2(Development Department a-1 group>2 group)' }, { id: 13, pid: 5, text: '3.2(Ministry of Personnel A)' }, { id: 19, pid: 5, text: '3.3(Ministry of Personnel B)' } ]; function translateData(data, idStr, pidStr, chindrenStr) { var result = [], temp = {}, id = idStr, pid = pidStr, children = chindrenStr, i = 0, j = 0, len = data.length; // Re-place the object in the array into a new object with the value of id as the key for (; i < len; i++) { // Create a temp object. Since the object is a reference type, modifying temp or data will cause the other party to change. temp[data[i][id]] = data[i]; // temp[a[i][id]] = JSON.parse(JSON.stringify(data[i])); in this case, data and temp are independent } // aVal stores the objects in the array, and gets the object whose key is pid in the new object. If there is for (; j < len; j++) { var dataVal = data[j], tempObj = temp[dataVal[pid]]; if (tempObj) { // If tempObj[children] does not exist, set tempObj[children] as an array !tempObj[children] && (tempObj[children] = []); tempObj[children].push(dataVal); } else { // Put dataVal in the result if it doesn't exist result.push(dataVal); } } console.log(data) return result; } document.getElementById("content").innerHTML = JSON.stringify(translateData(json, 'id', 'pid', 'chindren'), null, 2)
Complete code
<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>
<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" //Encapsulate function, easy to call function render(arr, ulClass) { //Set HTML as the first half of the ul tag pair to include the following in ul var html = '<ul class="' + ulClass + '">'; //Set the loop to traverse each item in the array, the longest is no longer than the length of the array, and traverse in turn for (var i = 0; i < arr.length; i++) { //Set the Li structure in the first level ul < li > < span > each title < / span ></li> // console.log(arr[i]) //Determine whether there is structure under the array 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") } //If so, add structure } //Set the back label of the first level li html += '</li>' } //Set the back label of the first level ul html += '</ul>' return html; } //Call the function, pass the parameter array data, assign it to the parent structure box of the first level ul, and generate the dynamic menu 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>