Several forms of tree structure menus in JavaScript_javascript skills
WBOY
Release: 2016-05-16 18:27:44
Original
1041 people have browsed it
1. Suspended layer tree (Tree) This tree structure implements a function similar to breadcrumb navigation. It listens to the mouse movement event of the node, and then displays the child nodes below or to the right of the node, and so on. Recursively displays the child nodes of child nodes.
User homepage blog settings article album message comment system There are a few small issues to pay attention to here. Firstly, this kind of tree structure is the absolute positioning of the suspended layer. When creating the layer, it must be placed directly on the body. Below, this is done to ensure that any layer can be covered in IE, because there are hidden rules for things like stacking context in IE. In addition, of course there is a select Can you cover me? An old question, here is to add an iframe element behind each floating layer. Of course, the menu at the same level only generates one iframe element. If the menu has several levels, it will generate several iframe masks. Then when the menu is displayed and hidden, it will be displayed and hidden at the same time. Hide iframe.
However, this kind of menu is not suitable for the front-end, because currently it only supports dynamically adding menu nodes in scripts, and cannot obtain menu nodes from existing html elements. For the sake of SEO and other front-end navigation, we usually dynamically add them in the background For output, if the menu has multiple levels, it is recommended not to exceed 2 levels. Customers will be too lazy to look at too many levels, but it is still very good to have a breadcrumb navigation display.
//ContextMenu var contextmenu = new ContextMenu(...{ container : document.getElementById('treemenu') }); contextmenu.push( ...{ html : 'Powered By: Jonllen', css : 'disabled'}); contextmenu.push( ...{ html : '', css : 'line'}); contextmenu.push( ...{ html : '刷新(R)', href : 'javascript:location.reload();'}); for(var i=0;icontextmenu.push(...{ id : menu[i].id, level : menu[i].level, parentId : menu[i].parentId, html : menu[i].name, href : menu[i].url }); } contextmenu.render(); //原有回调函数 var contextmenuOnShow = contextmenu.onShow; //设置新的回调函数 contextmenu.onShow = function (target, _this)...{ var item = target.treemenu || target.parentNode.treemenu; if( item ) ...{ var html = '添加' item.html '“子节点' (item.children.length 1) '”'; _this.push( ...{ html : html, click : function (e)...{ item.expand = false; var newItem = ...{ id : item.id '0' (item.children.length 1), level : item.level 1, parentId : item.id, html : item.html '子节点' (item.children.length 1), href : '#', css : 'item', createExpand : true }; item.children.push(newItem); treemenu.list.push(newItem); treemenu.renderChild(item); }, clickClose : true, index : 1, type : 'dynamic' }); _this.push( ...{ html : '删除节点“' item.html '”', click : function (e)...{ if( confirm('是否确认删除节点“' item.html '”?')) treemenu.remove(item); }, clickClose : true, index : 2, type : 'dynamic' }); } contextmenuOnShow(target, _this); };
So how to implement the "callback function"? In fact, it is very simple. When the function reaches a certain line of code, it runs a preset "callback function". It is a bit like an event mechanism, like binding multiple window.onload events. Since there may be bound functions before, record the previous functions first. , then set the newly bound function, and then call the previously bound function. The code shown above realizes that if the right-click element is a treemenu node, the add and delete treemenu node menu will be added in the right-click. The effect is shown in the node tree (TreeMenu) example below. We need to pay attention to the scope in the callback function. The this pointer points to the current callback function object, not the context in which the callback function is run. However, we can also use the call method to run the callback function in the current this context. Here I adopt the method of passing 2 parameters to the callback function, so that the callback function can easily obtain this object and other variables. This is commonly used in the Ajax Callback function. The custom right-click menu (ContextMenu) is only suitable for shortcut operations of some auxiliary functions. For example, if there are some OA systems with complex business functions, I will also use it in conjunction with the node tree (TreeMenu) below. If possible, try not to use the right-click menu. Firstly, users need to be trained in the habit of right-clicking. Secondly, customizing the right-click menu loses some functions of the original right-click menu, such as viewing source files. Here is the right-click menu area. Right-click me and you can see the properties. You can also select me and right-click to copy. Can you cover me? ContextMenu.js
3. Node Tree (TreeMenu) Node tree (TreeMenu) is the most used in our actual projects. The famous MzTreeVew of Meihuaxue on the Internet has been optimized for large amounts of data and is very efficient. But I don’t really like to adopt things. Since I don’t understand some things or why they do what they do, I want to try to “invent the wheel” myself. Of course, the function is definitely not as powerful as MzTreeVew. I did not do an efficiency test when the amount of data was large. I borrowed the pictures from MzTreeVew first.
Infinite-level node tree
To achieve infinite-level functions, if there are no tricks, it seems that the only way is recursion. However, it should be noted that there must be a correct condition to determine the return to avoid an infinite loop. In terms of data storage structure, generally our database stores id, name, and parentId fields. This structure is still stored in the tree structure. When expanding a tree node, we need to obtain all its child nodes based on the id and save them. , to avoid repeated traversal for the second time.
Hierarchical relationship structure
What I want to say here is that the HTML presented has a hierarchical relationship, and each tree node object has a hierarchical relationship. The HTML hierarchical relationship shows that the elements of the child nodes must be the child nodes of the elements of the parent node. Originally I thought this was not necessary. Later I found that only by doing this can the state of the child nodes be maintained. For example, if I click on a first-level node, I only need Expand all second-level nodes, and the status of third-level or fourth-level nodes does not need to be changed. The HTML structure is easy to implement with this hierarchical relationship support. Corresponding to this is the tree node object, which stores parent node objects, child node collection objects, reference elements, etc. to facilitate recursive calls. This information is attached to the corresponding DOM element.
With checkbox and radio selection
The needs of actual projects are complex and changeable. Sometimes we need to provide radio single selection function, and sometimes we may need to provide checkbox multi-selection function. In order to It is also necessary to directly obtain the selected value in the background and provide checkbox and radio selection functions. Of course, we can configure and specify whether to create a checkbox or radio during instantiation. Whether each node is selected during initialization can also be set and specified. What needs to be noted here is that we cannot specify the name attribute when we directly create a checkbox or radio. In a twist, Just think of it to achieve it.
var inputTemp = document.createElement('div'); inputTemp.innerHTML = ''; var inputElem = inputTemp.childNodes[0];
Tie only Define a click event
It looks like a more complicated tree structure, but in fact I only bound a click event to the outermost container element. In addition, the linkage of clicking the checkbox is also handled in this click event, because The element's event will bubble up and trigger to the parent element, and it is easy to use the event object event to get the trigger source element, so I can get whether you clicked on the checkbox or some other element, which is very convenient. The advantage of this is that you can focus on processing one event instead of adding events to each element, which fully demonstrates the elegance and beauty of the code.
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn