Details about the functions of the checkbox tree in Javascript

Source: Internet
Author: User

For the functions of the checkbox tree in Javascript, many people are not very familiar with the function of the checkbox tree. I hope this article will help you. After studying for a few days, I finally got my own tree. To sum up, we will leave it for future improvement.

As a UI control tree, the tree is very different from the data structure tree. It is divided into root nodes, branch nodes and leaf nodes. The root node has a subtree and does not belong to any other tree. A branch node has a subtree and is a node of A subtree. A leaf node only exists as a node of A subtree and does not have a subtree. However, the tree cannot be drawn. As shown in the following figure, the tree is separated from top to bottom by a row regardless of the way it looks on the webpage. Each line contains several images and text. These images are roughly divided into three types. One is the dotted line icon and the plus sign icon and the minus sign icon. I collectively refer to them as the link icon; the other is the folder icon used for decoration, or the earth on the root node, or a document on a leaf node, or a similar computer, apple, or recycle bin, I call it a decoration icon. Finally, it is a checkbox, which is divided into three states. There are so many types of icons that only the Root Branches and branches are closed and expanded. There are only six possibilities. Therefore, we have to divide the branches into common branches and the last branches, the same applies to leaf nodes. Because the link icon works very similar to the decoration icon, it seems that the decoration icon visually emphasizes the effect of clicking the link icon, so we can integrate them with CSS, to save a DOM.

Take the root node for analysis. On the surface, it has three icons, one text, essentially, there are only two icons, and the second exists as the first background. The text is located in the span element. If you want to click the text jump, you can also change it to element. In addition, the last DIV element is hidden. It is used to load and indent Subtrees. These four elements are located in a DIV. I call it the root node and set the index attribute to obtain the index of the parent node compared with the original data.

01. var data = [ 02.    [0,-1, "China" ], // Root Node 03.    [1,0, "Beijing" ], // Branch node 04.    [2,0, "Tianjin" ], // Leaf node 05.    [3,1, "City jurisdiction" ], // Branch node 06.    [4,3, "Dongcheng District" ], // Leaf node 07.    [5,3, "Xicheng district" ], // Leaf node 08.    [6,3, "Chongwen District" ], // Leaf node 09.    [7,3, "Chaoyang District" ], // Leaf node 10.    [8,3, "Fengtai District" ] // Leaf node 11. ]

Then we add some identification elements to the icon, Which is useless for style table control or event binding, because only an index is very weak. When we click the line icon, the plus sign or minus sign, how can we let the program know that it is clicked ?! We will give it a className, Which is collapse and unfold. As long as there are one of these two classes, we will reset its className. It turns out to be collapse and changed to unfold, and vice versa, and then change its src to achieve the purpose of switching the image. The decoration icon behind it is to use the style sheet to control the internal style), so when className changes, it will reflow and re-render the page. The difficulty lies in the checkbox. When you click it, there will be a series of reactions, replacing the checkbox of its parent node, changing itself, and then replacing its children and grandchildren. It has three states, and corresponds to three className. 0 indicates that the child element is not selected, 1 indicates that all child elements are selected, and 2 indicates that the child element is selected. The algorithm is very complex and rendering is very complicated. For example, if img is the checkbox icon, its parentNode is the node element of the tree. If it is not the root node, it must be wrapped by a DIV, img. parentNode.ParentNode. parentNode is the tree node element at the upper level. The second IMG element of this node is the checkbox on top of it. It is more complicated to access its lower-level checkbox! In short, recursion is used in multiple places. Let's look at the source code. Since I have never learned data structures and algorithms, the implementation is a little inferior, and there are only one hundred and fifty rows of functionality. Bug cannot be self-arranged. Therefore, do not use it for commercial purposes.

 
 
  1. VarGetPriorCheckbox =Function(Checkbox ){
  2. VarNode = checkbox. parentNode;// Obtain the corresponding Tree node 
  3. If(/Root/. test (node. className )){// Determine whether the root node is used 
  4. Return False;
  5. }Else{
  6. VarPriorNode = node. parentNode. parentNode;// Obtain the corresponding upper-level tree node 
  7. ReturnPriorNode. children [1];
  8. }
  9. }

<! Doctype html> <title> tree by situ zhengmei </title> <meta charset = "UTF-8"/> <meta name = "keywords" content = "Tree by situ zhengmei"/> <meta name = "description" content = "Tree by situ zhengmei"/> <p> Tree by situ zhengmei </p> <script type = "text/javascript"> Tree = function () {this. path = "http://images.cnblogs.com/cnblogs_com/rubylouvre/205314/o_"; this. name = "tree"; this. id = + new Date + parseInt (Math. random () * 100000); this. initialize. apply (this, argu Ments);} Tree. prototype = {constructor: Tree, initialize: function (config) {var me = this, renderTo = config. renderTo; me. tree = config. data; me. container = (typeof renderTo = "string ")? Document. getElementById (renderTo): renderTo) | document. body; me. panel = document. createElement ("div"); me. panel. setAttribute ("id", "tree" + me. id) me. container. insertBefore (me. panel, null); var id = "#" + me. panel. id; var sheet = document. createElement ('style'); sheet. type = 'text/css '; document. getElementsByTagName ('head') [0]. appendChild (sheet); var bg = "background: transparent url (" + me. path; var CssCode = id + "{font-size: 12px;} \ n" + id + "img {border: 0; vertical-align: middle ;} \ n "+ id +" span {vertical-align: bottom;} \ n "+ id + ". line {padding-left: 18px; "+ bg +" line.gif) repeat-y 0 0;} \ n "+ id + ". blank {margin-left: 18px;} \ n "+ id +" img. collapse {padding-right: 18px; "+ bg +" folder.gif) no-repeat right center;} \ n "+ // close the decoration icon of the Control Branch node) id + "img. unfold {padding-right: 18px; "+ bg +" folderopen.gif) no-repeat rig Ht center;} \ n "+ // display the decoration icon of the Control Branch node) id +" img. root {padding-right: 18px; "+ bg +" root.gif) no-repeat right center;} \ n "+ // controls the decoration icon id of the root node +" img. leaf {padding-right: 18px; "+ bg +" leaf.gif) no-repeat right center;} \ n "// controls the leaf node decoration icon if (! + "\ V1") {sheet.styleSheet.css Text = cssCode} else if (/a/[-1] = 'A') {sheet. innerHTML = cssCode} else {sheet. appendChild (document. createTextNode (cssCode);} // Add the root node var icon = me. makeImage ("nolines_plus", "collapse root") var checkbox0 = me. makeImage ("checkbox_0", "checkbox_0"); me. panel. innerHTML = me. makeTree (me. tree [0] [0], "B", 0, icon + checkbox0, me. tree [0] [2]); me. childs = []; me. checks = []; // origin loading click Count me. panel. onclick = function (e) {e = e | window. event; var node = e. srcElement? E. srcElement: e.tar get; var current = node. parentNode; var currentIndex = current. getAttribute ("index"); var currentPrefix = current. getAttribute ("prefix"); var currentLevel = current. getAttribute ("level"); var subtree = me. getSubtree (currentIndex); var children = current. children [3]; // Add a subtree set // if (subtree &&! Children) {children = document. createElement ("div"); var childs = []; for (var I = 0, length = subtree. length; I <length; I ++) {var isLimb = me. hasSubtree (subtree [I] [0]); var isLast = (I = subtree. length-1); var prefix = isLast? "Blank": "line"; icon = isLast? "Plusbottom": "plus"; if (isLimb) {icon = me. makeImage (icon, "collapse limb"); // decoration icon before the branches} else {icon = icon. replace (/plus/, "join"); // The line icon in front of the leaf node = me. makeImage (icon, "leaf"); // decoration icon in front of the leaf node} childs. push (subtree [I] [0]) children. innerHTML + = me. makeTree (subtree [I] [0], prefix, + currentLevel + 1, icon + checkbox0, subtree [I] [2])} me. childs [currentIndex] = childs; children. className = (currentPrefix =" Line ")? "Line": "blank"; current. insertBefore (children, null);} if (/collapse /. test (node. className) {// if you click the plus sign or minus sign icon node. src = node. src. replace (/plus/, "minus"); // change the node of the connection icon. className = node. className. replace ("collapse", "unfold"); // change the decoration icon children & (children. style. display = "block");} else if (/unfold /. test (node. className) {node. src = node. src. replace (/minus/, "plus"); // change the node of the connection icon. className = node. classNa Me. replace ("unfold", "collapse"); // change the decoration icon children & (children. style. display = "none");} if (/checkbox /. test (node. className) {// if you click the checkbox icon var checked = me. isChecked (node); // if it is true, --; if it is false, ++ me. setPriorCheckbox (current, checked); // It Must Be checkbox at the beginning, and false me is returned. setJuniorCheckbox (current, checked) }}, setJuniorCheckbox: function (node,/* Boolean */checked) {var checkbox = node. children [1]; var ReplaceCheckbox = checked? "Checkbox_0": "checkbox_1"; checkbox. src = checkbox. src. replace (/checkbox _ \ d/, replaceCheckbox); checkbox. className = replaceCheckbox; var index = node. getAttribute ("index"); if (!! This. childs [index]) {var length = this. childs [index]. length; this. checks [index] = checked? Length: 0; if (length> 0) {var children = node. children [3]. children; while (-- length> = 0) {this. setJuniorCheckbox (children [length], checked) }}, setPriorCheckbox: function (node,/* Boolean */checked) {// set the checkbox var index = node of the upper-level tree. getAttribute ("index"); var prior = node. parentNode. parentNode; var priorIndex = this. tree [index] [1]; var priorCheckbox = prior. children [1]; var priorLevel = prior. GetAttribute ("level"); var priorCount = this. checks [priorIndex] | 0; checked? PriorCount --: priorCount ++; (priorCount <0) & (priorCount = 0) this. checks [priorIndex] = priorCount; if (!! PriorCheckbox) {// when priorIndex is equal to-1, // priorCheckbox does not exist // me. childs [priorIndex] is undefined, and there is no checked length = (priorCount = this. childs [priorIndex]. length); var replaceCheckbox = checked? "Checkbox_1": "checkbox_2"; // If checkbox_1 is all selected and checkbox_2 is not all selected // If checkbox_1 is all selected, the upper-level ++ is used to set checked to false priorCheckbox. src = priorCheckbox. src. replace (/checkbox _ \ d/, replaceCheckbox );//???????? PriorCheckbox. className = replaceCheckbox;} if (priorLevel> 0) {// The root node does not have priorCheckbox, and priorLevel is equal to-1 this. setPriorCheckbox (prior, checked) ;}}, isChecked: function (node) {// if it is checkbox_0, false is returned, and true return node is returned for checkbox_1 and checkbox_2. src. slice (-5,-4)> 0 ;}, makeImage: function (image) {var status = ""; if (arguments [1]! = Null) {status = "class = '" + arguments [1] + "'";} return " "}, makeTree: function (index, prefix, level, images, text) {var builder = []; builder. push ("<div index = '"); builder. push (index); builder. push ("'prefix = '") builder. push (prefix); builder. push ("'level = '") builder. push (level); builder. push ("'>"); builder. push (images); builder. push ("<span>"); builder. push (text); builder. push ("</span> </div>") return builder. join ('') ;}, hasSubtree: function (p) {var tree = this. tree; for (var I = 0, length = tree. length; I <length; I ++) {if (this. tree [I] [1] = p) {return true ;};}; return false ;}, getSubtree: function (p) {var subtree = [], tree = this. tree; for (var I = 0, length = tree. length; I <length; I ++) {if (tree [I] [1] = p) {subtree. push (tree [I]) ;};}; return subtree }}var data = [0,-1, "foreground technology, "presentation layer"], [, "CSS"], [, "CSS resource"], [, "CSS3 prospective, "web standard knowledge"], [6, 1, "graphics"], [7, 6, "SVG"], [8, 6, "VML"], [9, 6, "canvas"], [10, 0, "structural layer"], [11, 10, "HTML"], [12, 10, "microformat"], [13, 10, "XML"], [14, 13, "XPath"], [, "behavior layer"], [, "core"], [, "variables and parameters, "object and inheritance"], [, "functions and closures"], [20, 16, "algorithms"], [, 16, "Advanced Technology"], [, 21, "Cross-origin request"], [, "acceleration technology"], [, 21, "Local Storage"], [, 21, "function hijacking, "Framework Design"], [27,26, "Ext"], [28,26, "dojo"], [29,26, "mootools"], [30,15, "Ajax"], [, "DOM"], [, "BOM"] window. onload = function () {var tree = new Tree ({renderTo: "test", data: data });} </script> <div id = "test"> </div>

Original article title: javascript checkbox tree

Link: http://www.cnblogs.com/rubylouvre/archive/2009/10/26/1589692.html

  1. Analysis on using Javascript to obtain random colors
  2. What is JSON? Data format prepared for JavaScript
  3. 10 most commonly used JavaScript udfs
  4. Some extended thoughts on loading JavaScript events
  5. Summary of JavaScript usage: From BOM and DOM

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.