Create a high-performance treeview (asp.net) _jquery based on jquery

Source: Internet
Author: User
Tags extend tagname unique id visibility

According to my project practice, there are mainly several key points:

1: Static tree support, that is, all the data loaded to the client at a one-time.
2: Asynchronous tree, that is, only one level or several levels of nodes are loaded at a time, and child nodes can load data asynchronously.
The 3:checkbox tree (possibly a static tree or an asynchronous tree) is used to select (such as selecting an organization, selecting a data dictionary item), and so on, preferably to support node cascade (This is a difficult point)
4: Able to carry large amount of data, and performance excellence
5: Able to work well in the mainstream browser

Then I'm going to create the TreeView to achieve this 5 main indicators.

Look at the effect chart first

The above picture is the data tree of the Chinese administrative area, the total node is 3500+.

So we're going to start the work;

1: The first identified node DOM structure (that is, what kind of HTML to build the node)

    • Compared to the soil is table set table (style good control, but large data volume, and a deeper level of the tree, this structure must not be able to withstand)
    • There is a relatively new way of the UL set Li, which is now a lot of books to take the way, such as Jquery.treeview is the use of this format, the advantages are more obvious is the structure concise and clear,
      And in the browser does not support JS, the same can also show the shape of the tree (in fact, I can ignore), But Jquery.treeview nodes in IE, especially IE6 under the internal element can not be stretched, (ie7,8 when reaching a certain depth can not be stretched), please strange phenomenon (I guess because of the use of padding to do indentation, Margin-left: Negative to control the position of the icon, but it is difficult to modify also larger), in this case book deformation (Jquery.treeview) has this problem, only by setting the width of the node to solve.

Node structure of Jquery.treeview

Jquery.treeview IE6 under the third stage is dislocation

IE8 down to level 5th

    • There are some of the way div set table, csdn navigation tree is this, is a compromise method (node is not too complex, and CSS is relatively good to write), as shown in the following figure

And I used the second way, but the indentation is the way to fill in the blanks, that is, the position of indentation with blank pictures to avoid the problem of Jquery.treeview

My tree node structure

We can write CSS by defining the HTML of the node. With the effect diagram, there is a node structure and then the CSS is written

Here is the complete code for CSS

Copy Code code as follows:



. ie. bbit-tree. bbit-tree-bwrap{


}


. Bbit-tree Ul,.bbit-tree Li


{


List-style-type:none;


margin:0px;


padding:0px;


}


. bbit-tree-body


{


font-size:12px;


}


Bbit-tree-icon, Bbit-tree-ec-icon,. Bbit-tree-node-cb,.bbit-tree-elbow-line,. Bbit-tree-elbow,. Bbit-tree-elbow-end, Bbit-tree-elbow-plus,. Bbit-tree-elbow-minus,. Bbit-tree-elbow-end-plus,. bbit-tree-elbow-end-minus{


border:0 none;


height:18px;


margin:0;


padding:0;


Vertical-align:top;


width:16px;


Background-repeat:no-repeat;


}


. BBIT-TREE-NODE-CB


{


height:16px;


}


. bbit-tree-node-collapsed. Bbit-tree-node-icon, bbit-tree-node-expanded Bbit-tree-node-icon. Bbit-tree-node-leaf. bbit-tree-node-icon{


border:0 none;


height:18px;


margin:0;


padding:0;


Vertical-align:top;


width:16px;


Background-position:center;


Background-repeat:no-repeat;


}


. ie. bbit-tree-node-indent img,. ie. bbit-tree-node-icon,. ie. bbit-tree-ec-icon {


Vertical-align:middle!important;


}


. Bbit-tree-noicon. bbit-tree-node-icon{


width:0; height:0;


}


/* No Line styles style * *


. Bbit-tree-no-lines. bbit-tree-elbow{


Background:transparent;


}


. Bbit-tree-no-lines. bbit-tree-elbow-end{


Background:transparent;


}


. Bbit-tree-no-lines. bbit-tree-elbow-line{


Background:transparent;


}


/* Arrows Vista system tree style only arrow/


. bbit-tree-arrows. bbit-tree-elbow{


Background:transparent;


}


. bbit-tree-arrows. bbit-tree-elbow-plus{


Background:transparent no-repeat 0 0;


}


. bbit-tree-arrows. bbit-tree-elbow-minus{


Background:transparent no-repeat-16px 0;


}


. bbit-tree-arrows. bbit-tree-elbow-end{


Background:transparent;


}


. bbit-tree-arrows. bbit-tree-elbow-end-plus{


Background:transparent no-repeat 0 0;


}


. bbit-tree-arrows. bbit-tree-elbow-end-minus{


Background:transparent no-repeat-16px 0;


}


. bbit-tree-arrows. bbit-tree-elbow-line{


Background:transparent;


}


. bbit-tree-arrows. Bbit-tree-ec-over. bbit-tree-elbow-plus{


BACKGROUND-POSITION:-32PX 0;


}


. bbit-tree-arrows. Bbit-tree-ec-over. bbit-tree-elbow-minus{


BACKGROUND-POSITION:-48PX 0;


}


. bbit-tree-arrows. Bbit-tree-ec-over. bbit-tree-elbow-end-plus{


BACKGROUND-POSITION:-32PX 0;


}


. bbit-tree-arrows. Bbit-tree-ec-over. bbit-tree-elbow-end-minus{


BACKGROUND-POSITION:-48PX 0;


}


Bbit-tree-elbow-plus,. Bbit-tree-elbow-minus,. Bbit-tree-elbow-end-plus,. bbit-tree-elbow-end-minus{


Cursor:pointer;


}


. IE ul.bbit-tree-node-ct{


font-size:0;


line-height:0;


Zoom:1;


}


. bbit-tree-node{


White-space:nowrap;


}


. bbit-tree-node-el {


line-height:18px;


Cursor:default;


/* cursor:pointer;*/


}


. Bbit-tree-node a{


Text-decoration:none;


-khtml-user-select:none;


-moz-user-select:none;


-webkit-user-select:ignore;


-kthml-user-focus:normal;


-moz-user-focus:normal;


-moz-outline:0 none;


outline:0 none;


}


. Bbit-tree-node a span{


Text-decoration:none;


padding:1px 3px 1px 2px;


}


. Bbit-tree-node. bbit-tree-node-disabled. bbit-tree-node-icon{


-moz-opacity:0.5;


opacity:.5;


Filter:alpha (OPACITY=50);


}


. Bbit-tree-node. bbit-tree-node-inline-icon{


Background:transparent;


}


. Bbit-tree-node a:hover{


Text-decoration:none;


}





/* fix for IE rootvisible:false issue, fix a iedebug * *


. bbit-tree-root {


Zoom:1;


}





/*********** here is the icon, can be replaced here Oh *****************/


. bbit-tree-node-expanded. bbit-tree-node-icon{


Background-image:url (images/tree/folder-open.gif);


}


. bbit-tree-node-leaf. bbit-tree-node-icon{


Background-image:url (images/tree/leaf.gif);


}


. bbit-tree-node-collapsed. bbit-tree-node-icon{


Background-image:url (images/tree/folder.gif);


}


. bbit-tree-node-loading. bbit-tree-node-icon{


Background-image:url (images/tree/loading.gif)!important;


}


. Bbit-tree-node. Bbit-tree-node-inline-icon {


Background-image:none;


}


. bbit-tree-node-loading a span{


Font-style:italic;


Color: #444444;


}


. Bbit-tree-lines. bbit-tree-elbow{


Background-image:url (images/tree/elbow.gif);


}


. Bbit-tree-lines. bbit-tree-elbow-plus{


Background-image:url (images/tree/elbow-plus.gif);


}


. Bbit-tree-lines. bbit-tree-elbow-minus{


Background-image:url (images/tree/elbow-minus.gif);


}


. Bbit-tree-lines. bbit-tree-elbow-end{


Background-image:url (images/tree/elbow-end.gif);


}


. Bbit-tree-lines. bbit-tree-elbow-end-plus{


Background-image:url (images/tree/elbow-end-plus.gif);


}


. Bbit-tree-lines. bbit-tree-elbow-end-minus{


Background-image:url (images/tree/elbow-end-minus.gif);


}


. Bbit-tree-lines. bbit-tree-elbow-line{


Background-image:url (images/tree/elbow-line.gif);


}


. Bbit-tree-no-lines. bbit-tree-elbow-plus{


Background-image:url (images/tree/elbow-plus-nl.gif);


}


. Bbit-tree-no-lines. bbit-tree-elbow-minus{


Background-image:url (images/tree/elbow-minus-nl.gif);


}


. Bbit-tree-no-lines. bbit-tree-elbow-end-plus{


Background-image:url (images/tree/elbow-end-plus-nl.gif);


}


. Bbit-tree-no-lines. bbit-tree-elbow-end-minus{


Background-image:url (images/tree/elbow-end-minus-nl.gif);


}


. bbit-tree-arrows. bbit-tree-elbow-plus{


Background-image:url (images/tree/arrows.gif);


}


. bbit-tree-arrows. bbit-tree-elbow-minus{


Background-image:url (images/tree/arrows.gif);


}


. bbit-tree-arrows. bbit-tree-elbow-end-plus{


Background-image:url (images/tree/arrows.gif);


}


. bbit-tree-arrows. bbit-tree-elbow-end-minus{


Background-image:url (images/tree/arrows.gif);


}


/*treenode selected disabled of some colors, font style * *


. bbit-tree-node{


Color: #000;


Font:normal 11px Arial, Tahoma, Helvetica, Sans-serif;


}


. Bbit-tree-node a{


Color: #000;


}


. Bbit-tree-node a span{


Color: #000;


}


. Bbit-tree-node. bbit-tree-node-disabled a span{


Color:gray!important;


}


. Bbit-tree-node. bbit-tree-node-over {


Background-color: #eee;


}


. Bbit-tree-node. bbit-tree-selected {


Background-color: #d9e8fb;


}





Above the basic style of the tree, defines a style with + number line and + number without line

That's the style with the + line.

All the pictures used in the CSS

2: Determine the data structure

Copy Code code as follows:

var menudata = [{
ID: "0.1",//unique ID can be
Text: "Beyondbit UI Demo",
Haschildren:true,
Isexpand:true,
Complete:true,
ChildNodes: [{
ID: "0.1.1",
Text: "Date Selection",
Haschildren:true,
Isexpand:false,
Complete:true,
ChildNodes: [{
ID: "0.1.1.1",
Text: "Control demo",
Value: "Testpages/datepickerdemo.htm",
Haschildren:false,
Isexpand:false,
Complete:true,
Childnodes:null
},
...
]



The advantage of such a structure is that the data itself is layered, very useful for traversal, and will be seen in subsequent cascading associations


3: Face well done, then start lining up, scripting (Javascript)


I am a jquery supporter, so the natural JS framework is naturally based on jquery


First the complete code, then the analysis


Copy Code code as follows:



/****************************************


Author:xuanye.wan@gmail.com


page:http://xuanye.cnblogs.com/


***************************************/


(function ($) {


$.fn.swapclass = function (c1, C2) {


Return This.removeclass (C1). addclass (C2);


}


$.fn.switchclass = function (c1, C2) {


if (This.hasclass (C1)) {


Return This.swapclass (c1, C2);


}


else {


Return This.swapclass (C2, C1);


}


}


$.fn.treeview = function (settings) {


var Dfop =


{


Method: "POST",


DataType: "JSON",


Url:false,


Cbiconpath: "/images/icons/",


Icons: ["Checkbox_0.gif", "Checkbox_1.gif", "Checkbox_2.gif"],


Showcheck:false,//whether to display the selection


Oncheckboxclick:false,//event triggered when checkstate state changes, but does not trigger changes caused by cascade selection


Onnodeclick:false,


Cascadecheck:true,


Data:null,


Clicktoggle:true,//Click on the node expansion and contraction child nodes


Theme: "Bbit-tree-arrows"//bbit-tree-lines, Bbit-tree-no-lines,bbit-tree-arrows


}


$.extend (Dfop, settings);


var treenodes = Dfop.data;


var me = $ (this);


var id = me.attr ("id");


if (id = = NULL | | | id = = "") {


id = "Bbtree" + New Date (). GetTime ();


ME.ATTR ("id", id);


}


var html = [];


Buildtree (dfop.data, HTML);


Me.addclass ("Bbit-tree"). HTML (Html.join (""));


Initevent (Me);


html = NULL;


Pre-loading pictures


if (Dfop.showcheck) {


for (var i = 0; i < 3; i++) {


var im = new Image (16,16);


IM.SRC = Dfop.cbiconpath + dfop.icons[i];


}


}


Region


function Buildtree (data, HT) {


Ht.push ("<div class= ' Bbit-tree-bwrap ' >"); Wrap;


Ht.push ("<div class= ' bbit-tree-body ' >"); Body;


Ht.push ("<ul class= ' Bbit-tree-root", Dfop.theme, "' >"); Root


var L = data.length;


for (var i = 0; i < L; i++) {


Buildnode (Data[i], HT, 0, I, i = = l-1);


}


Ht.push ("</ul>"); Root and;


Ht.push ("</div>"); Body End;


Ht.push ("</div>"); Wrap end;


}


Endregion


function Buildnode (ND, HT, deep, path, isend) {


Ht.push ("<li class= ' Bbit-tree-node ' >");


Ht.push ("<div id=", id, "_", Nd.id, "' tpath= '", Path, "' unselectable= '");


var cs = [];


Cs.push ("Bbit-tree-node-el");


if (Nd.haschildren) {


Cs.push (Nd.isexpand?) "bbit-tree-node-expanded": "bbit-tree-node-collapsed");


}


else {


Cs.push ("Bbit-tree-node-leaf");


}


if (nd.classes) {Cs.push (nd.classes);}


Ht.push ("class= '", Cs.join (""), "' >");


Span Indent


Ht.push ("<span class= ' bbit-tree-node-indent ' >");


if (deep = = 1) {


Ht.push ("<img class= ' Bbit-tree-icon ' src= ')." /themes/shared/images/s.gif '/> ');


}


else if (Deep > 1) {


Ht.push ("<img class= ' Bbit-tree-icon ' src= ')." /themes/shared/images/s.gif '/> ');


for (var j = 1; j < Deep; J + +) {


Ht.push ("<img class= ' bbit-tree-elbow-line ' src= ')." /themes/shared/images/s.gif '/> ');


}


}


Ht.push ("</span>");


Img


cs.length = 0;


if (Nd.haschildren) {


if (Nd.isexpand) {


Cs.push (isend?) "Bbit-tree-elbow-end-minus": "Bbit-tree-elbow-minus");


}


else {


Cs.push (isend?) "Bbit-tree-elbow-end-plus": "Bbit-tree-elbow-plus");


}


}


else {


Cs.push (isend?) "Bbit-tree-elbow-end": "Bbit-tree-elbow");


}


Ht.push ("<img class= ' Bbit-tree-ec-icon", Cs.join (""), "' src= '". /themes/shared/images/s.gif '/> ');


Ht.push ("<img class= ' Bbit-tree-node-icon ' src= ')." /themes/shared/images/s.gif '/> ');


CheckBox


if (Dfop.showcheck && nd.showcheck) {


if (nd.checkstate = null | | nd.checkstate = = undefined) {


nd.checkstate = 0;


}


Ht.push ("<img id= '", ID, "_", Nd.id, "_CB" class= ' BBIT-TREE-NODE-CB ' "src=", Dfop.cbiconpath, dfop.icons[ Nd.checkstate], "'/>");


}


A


Ht.push ("<a hidefocus class= ' bbit-tree-node-anchor tabindex=1 ' href= ' Javascript:void" (0); ' > ");


Ht.push ("<span unselectable= ' on ' >", Nd.text, "</span>");


Ht.push ("</a>");


Ht.push ("</div>");


Child


if (Nd.haschildren) {


if (Nd.isexpand) {


Ht.push ("<ul class= ' bbit-tree-node-ct ' style= ' z-index:0;") position:static; visibility:visible; Top:auto; Left:auto; ' > ");


if (ND. ChildNodes) {


var L = nd. Childnodes.length;


for (var k = 0; k < l; k++) {


nd. childnodes[k].parent = nd;


Buildnode (nd. CHILDNODES[K], HT, deep + 1, Path + "." + k, k = = L-1);


}


}


Ht.push ("</ul>");


}


else {


Ht.push ("<ul style= ' Display:none;") ></ul> ");


}


}


Ht.push ("</li>");


Nd.render = true;


}


function GetItem (path) {


var ap = Path.split (".");


var t = treenodes;


for (var i = 0; i < ap.length; i++) {


if (i = = 0) {


t = T[ap[i]];


}


else {


t = T.childnodes[ap[i]];


}


}


return t;


}


function check (item, state, type) {


var pstate = item.checkstate;


if (type = = 1) {


Item.checkstate = State;


}


else {//traced


var cs = Item. ChildNodes;


var L = cs.length;


var ch = true;


for (var i = 0; i < L; i++) {


if (state = = 1 && cs[i].checkstate!= 1) | | | state = = 0 && cs[i].checkstate!= 0) {


ch = false;


Break


}


}


if (CH) {


Item.checkstate = State;


}


else {


Item.checkstate = 2;


}


}


Change Show


if (item.render && pstate!= item.checkstate) {


var et = $ ("#" + ID + "_" + item.id + "_CB");


if (et.length = = 1) {


Et.attr ("src", Dfop.cbiconpath + dfop.icons[item.checkstate]);


}


}


}


Traversing child nodes


function Cascade (FN, item, args) {


if (FN (item, args, 1)!= false) {


if (item. ChildNodes!= null && item. Childnodes.length > 0) {


var cs = Item. ChildNodes;


for (var i = 0, len = cs.length i < len; i++) {


Cascade (FN, cs[i], args);


}


}


}


}


Bubbles of Ancestors


Function Bubble (FN, item, args) {


var p = item.parent;


while (p) {


if (FN (p, args, 0) = = False) {


Break


}


p = p.parent;


}


}


function Nodeclick (e) {


var path = $ (this). attr ("Tpath");


var et = E.target | | E.srcelement;


var item = getitem (path);


Debugger


if (Et.tagname = "IMG") {


+ number needs to be expanded


if ($ (ET). Hasclass ("Bbit-tree-elbow-plus") | | $ (ET). Hasclass ("Bbit-tree-elbow-end-plus")) {


var ul = $ (this). Next (); "Bbit-tree-node-ct"


if (Ul.hasclass ("bbit-tree-node-ct")) {


Ul.show ();


}


else {


var deep = Path.split ("."). Length


if (item.complete) {


Item. ChildNodes!= null && asnybuild (item. ChildNodes, deep, PATH, UL, item);


}


else {


$ (this). addclass ("bbit-tree-node-loading");


ASNYLOADC (UL, item, function (data) {


Item.complete = true;


Item. childnodes = data;


Asnybuild (data, deep, PATH, UL, item);


});


}


}


if ($ (ET). Hasclass ("Bbit-tree-elbow-plus")) {


$ (ET). Swapclass ("Bbit-tree-elbow-plus", "Bbit-tree-elbow-minus");


}


else {


$ (ET). Swapclass ("Bbit-tree-elbow-end-plus", "Bbit-tree-elbow-end-minus");


}


$ (this). Swapclass ("bbit-tree-node-collapsed", "bbit-tree-node-expanded");


}


else if ($ (ET). Hasclass ("Bbit-tree-elbow-minus") | | $ (ET). Hasclass ("Bbit-tree-elbow-end-minus")) {//-number needs to shrink


$ (this). Next (). Hide ();


if ($ (ET). Hasclass ("Bbit-tree-elbow-minus")) {


$ (ET). Swapclass ("Bbit-tree-elbow-minus", "Bbit-tree-elbow-plus");


}


else {


$ (ET). Swapclass ("Bbit-tree-elbow-end-minus", "Bbit-tree-elbow-end-plus");


}


$ (this). Swapclass ("bbit-tree-node-expanded", "bbit-tree-node-collapsed");


}


else if ($ (ET). Hasclass ("BBIT-TREE-NODE-CB"))//Click CheckBox


{


var s = item.checkstate!= 1? 1:0;


var r = true;


if (Dfop.oncheckboxclick) {


R = Dfop.oncheckboxclick.call (ET, item, s);


}


if (R!= false) {


if (Dfop.cascadecheck) {


Traverse


Cascade (check, item, s);


Traced back


Bubble (check, item, s);


}


else {


Check (item, S, 1);


}


}


}


}


else {


if (Dfop.citem) {


$ ("#" + ID + "_" + dfop.citem.id). Removeclass ("bbit-tree-selected");


}


Dfop.citem = Item;


$ (this). addclass ("bbit-tree-selected");


if (Dfop.onnodeclick) {


Dfop.onnodeclick.call (this, item);


}


}


}


function Asnybuild (nodes, deep, PATH, UL, Pnode) {


var L = nodes.length;


if (L > 0) {


var ht = [];


for (var i = 0; i < L; i++) {


Nodes[i].parent = Pnode;


Buildnode (Nodes[i], HT, deep, Path + "." + I, i = = l-1);


}


Ul.html (Ht.join (""));


HT = NULL;


Initevent (UL);


}


Ul.addclass ("Bbit-tree-node-ct"). CSS ({"Z-index": 0, Position: "Static", Visibility: "Visible", Top: "Auto", Left: "Auto ", Display:" "});


Ul.prev (). Removeclass ("bbit-tree-node-loading");


}


function ASNYLOADC (PUL, Pnode, callback) {


if (Dfop.url) {


var param = Builparam (pnode);


$.ajax ({


Type:dfop.method,


Url:dfop.url,


Data:param,


DataType:dfop.datatype,


Success:callback,


Error:function (e) {alert ("Error occur!");}


});


}


}


function Builparam (node) {


var p = [{name: ' id ', value:encodeuricomponent (node.id)}


, {name: ' Text ', Value:encodeuricomponent (Node.text)}


, {name: ' Value ', Value:encodeuricomponent (Node.value)}


, {name: "CheckState", value:node.checkstate}];


return p;


}


function Initevent (parent) {


var nodes = $ ("Li.bbit-tree-node>div", parent);


Nodes.each (function (e) {


$ (this). Hover (function () {


$ (this). addclass ("Bbit-tree-node-over");


}, function () {


$ (this). Removeclass ("Bbit-tree-node-over");


})


. Click (Nodeclick)


. Find ("Img.bbit-tree-ec-icon"). each (function (e) {


if (!$ (this). Hasclass ("Bbit-tree-elbow")) {


$ (this). Hover (function () {


$ (this). Parent (). addclass ("Bbit-tree-ec-over");


}, function () {


$ (this). Parent (). Removeclass ("Bbit-tree-ec-over");


});


}


});


});


}


function Getck (items, C, fn) {


for (var i = 0, L = items.length i < l; i++) {


Items[i].checkstate = = 1 && c.push (FN (items[i));


if (items[i). ChildNodes!= null && items[i]. Childnodes.length > 0) {


GETCK (Items[i]. ChildNodes, C, FN);


}


}


}


me[0].t = {


Getselectednodes:function () {


var s = [];


GETCK (treenodes, S, function (item) {return item});


return s;


},


Getselectedvalues:function () {


var s = [];


GETCK (treenodes, S, function (item) {return item.value});


return s;


},


Getcurrentitem:function () {


return dfop.citem;


}


};


return me;


}


Gets the value array of all the selected nodes


$.fn.gettsvs = function () {


if (this[0].t) {


return This[0].t.getselectedvalues ();


}


return null;


}


Gets the item array for all selected nodes


$.fn.gettsns = function () {


if (this[0].t) {


return This[0].t.getselectednodes ();


}


return null;


}


$.FN.GETTCT = function () {


if (this[0].t) {


return This[0].t.getcurrentitem ();


}


return null;


}


}) (JQuery);





Step One: Nature is the first step in all jquery controls is to build this shelf, compatible with jquery and $ avoid closures, avoid conflicts with other class libraries, and accept an argument (is an object)


Copy Code code as follows:

;(function ($) {
You can also use $.fn.extend (treeview:function (setting) {})
$.fn.treeview = function (settings) {
}
}) (JQuery);



The second step: add some parameter default parameters to the control, and call the method $.extend to override the default (if not the default) for the arguments at the end of the call


Copy Code code as follows:

var Dfop ={
Method: "POST",//default submit data by post
DataType: "JSON",//data type is JSON
url:false,//The URL of the asynchronous request
Cbiconpath: "/images/icons/",//checkbox icon's directory location
Icons: ["Checkbox_0.gif", "Checkbox_1.gif", "Checkbox_2.gif"],//checkbxo three-state picture
Showcheck:false,//Whether a checkbox is displayed
Oncheckboxclick:false,//events triggered when clicking a checkbox
onnodeclick:false,//Click Node triggered time
cascadecheck:true,//whether cascading is enabled
data:null,//Initialization of data
Theme: "Bbit-tree-arrows"///Three style alternative bbit-tree-lines, bbit-tree-no-lines,bbit-tree-arrows
}
Overwrite the default with incoming arguments, leave without passing
$.extend (Dfop, settings);



Step three: Generate the HTML for the default data (based on our analysis node's DOM structure, data structure, generation node that is very simple), add it to the current container. And finally, registering events. Here is a very important place, that is lazy loading (no expanded node HTML is not generated), which requires us to maintain a set of data within the tree (very small overhead), for performance improvement that is quite obvious. Another important place is to use the HTML that generates all the expanded nodes at once and to generate the DOM through the innerHTML property, rather than through the append operation, because the direct operation innerHTML faster than the DOM native method (more nodes, n larger), remember!


Copy Code code as follows:

var treenodes = Dfop.data; The internal data, in fact, directly with Dfop.data can also
var me = $ (this);
var id = me.attr ("id");
if (id = = NULL | | | id = = "") {
id = "Bbtree" + New Date (). GetTime ();
ME.ATTR ("id", id);
}//globally Unique ID
var html = [];
Buildtree (dfop.data, HTML);//Generate expansion node Html,push to array
Me.addclass ("Bbit-tree"). HTML (Html.join (""));
Initevent (me);//Initialization Event
html = NULL;



In the process of node generation, we can also produce the path of nodes (node paths) to facilitate retrieval


Copy Code code as follows:

if (Nd.haschildren) {//presence of child nodes
if (Nd.isexpand) {//node is expanded then output child node
Ht.push ("<ul class= ' bbit-tree-node-ct ' style= ' z-index:0;") position:static; visibility:visible; Top:auto; Left:auto; ' > ");
if (ND. ChildNodes) {
var L = nd. Childnodes.length;
for (var k = 0; k < l; k++) {//recursive call and Production node path
nd. childnodes[k].parent = nd;
Buildnode (nd. CHILDNODES[K], HT, deep + 1, Path + "." + k, k = = L-1);
}
}
Ht.push ("</ul>");
}
else {//otherwise is to be output status
Ht.push ("<ul style= ' Display:none;") ></ul> ");
}
}



Registers an event, accepts the argument parent, that is, starting an attached event from a parent node (because the event is on each node, and if the effect is canceled, the event can be directly appended to the srcelement to distribute the hover through event)


Copy Code code as follows:

function Initevent (parent) {
var nodes = $ ("Li.bbit-tree-node>div", parent);
Nodes.each (function (e) {
$ (this). Hover (function () {
$ (this). addclass ("Bbit-tree-node-over"); Style changes for mouse floating nodes
}, function () {
$ (this). Removeclass ("Bbit-tree-node-over");
})
. Click (nodeclick)//node's onclick event, this is the focus OH
. Find ("Img.bbit-tree-ec-icon"). each (function (e) {//arrow hover event, in order to achieve Vista that style of
if (!$ (this). Hasclass ("Bbit-tree-elbow")) {
$ (this). Hover (function () {
$ (this). Parent (). addclass ("Bbit-tree-ec-over");
}, function () {
$ (this). Parent (). Removeclass ("Bbit-tree-ec-over");
});
}
});
});
}



The main thing here is node's Click event, because he has to deal with a lot of things, such as the expansion of the tree contraction (such as the fruit node does not exist, but HasChildren is true, while the complete property is not true, you need to asynchronously load child nodes, such as child nodes exist, But without render then render), click the checkbox to start cascading events and Oncheckbox events, click on the other Nodeonclick events that trigger the configuration criteria, All this distinguishes the clicked object by the class of the source element of the previous event


Copy Code code as follows:



function Nodeclick (e) {


var path = $ (this). attr ("Tpath");//Get node path


var et = E.target | | e.srcelement;//Get Event Source


var item = getitem (path);//Get Data for node from path


Debugger


if (Et.tagname = "IMG") {


+ number needs to be expanded, processing plus minus sign


if ($ (ET). Hasclass ("Bbit-tree-elbow-plus") | | $ (ET). Hasclass ("Bbit-tree-elbow-end-plus")) {


var ul = $ (this). Next (); "Bbit-tree-node-ct"


if (Ul.hasclass ("bbit-tree-node-ct")) {


Ul.show ();


}


else {


var deep = Path.split ("."). Length


if (item.complete) {


Item. ChildNodes!= null &amp;&amp; asnybuild (item. ChildNodes, deep, PATH, UL, item);


}


else {


$ (this). addclass ("bbit-tree-node-loading");


ASNYLOADC (UL, item, function (data) {


Item.complete = true;


Item. childnodes = data;


Asnybuild (data, deep, PATH, UL, item);


});


}


}


if ($ (ET). Hasclass ("Bbit-tree-elbow-plus")) {


$ (ET). Swapclass ("Bbit-tree-elbow-plus", "Bbit-tree-elbow-minus");


}


else {


$ (ET). Swapclass ("Bbit-tree-elbow-end-plus", "Bbit-tree-elbow-end-minus");


}


$ (this). Swapclass ("bbit-tree-node-collapsed", "bbit-tree-node-expanded");


}


else if ($ (ET). Hasclass ("Bbit-tree-elbow-minus") | | $ (ET). Hasclass ("Bbit-tree-elbow-end-minus")) {//-number needs to shrink


$ (this). Next (). Hide ();


if ($ (ET). Hasclass ("Bbit-tree-elbow-minus")) {


$ (ET). Swapclass ("Bbit-tree-elbow-minus", "Bbit-tree-elbow-plus");


}


else {


$ (ET). Swapclass ("Bbit-tree-elbow-end-minus", "Bbit-tree-elbow-end-plus");


}


$ (this). Swapclass ("bbit-tree-node-expanded", "bbit-tree-node-collapsed");


}


else if ($ (ET). Hasclass ("BBIT-TREE-NODE-CB"))//Click CheckBox


{


var s = item.checkstate!= 1? 1:0;


var r = true;


if (Dfop.oncheckboxclick) {//Trigger configured function


R = Dfop.oncheckboxclick.call (ET, item, s);


}


if (R!= false) {//If the return value is not false, the Checkbxo change is valid


if (Dfop.cascadecheck) {//Allow cascade to be triggered


Traverse


Cascade (check, item, s);//down-associated


Traced back


Bubble (check, item, s); Correlate up


}


else {


Check (item, S, 1);/or just be yourself.


}


}


}


}


else {//click anywhere else


if (Dfop.citem) {//Previous current node


$ ("#" + ID + "_" + dfop.citem.id). Removeclass ("bbit-tree-selected");


}


Dfop.citem = item;//current node of this time


$ (this). addclass ("bbit-tree-selected");


if (Dfop.onnodeclick) {


Dfop.onnodeclick.call (this, item);


}


}


}





Expand the node, the asynchronous request part of the code should not be very complicated to complain, the key to the Cascade


Cascade has two problems to deal with, the first is to traverse the child node, the second is traced back to the ancestor node, because our data structure these two operations are very simple


Copy Code code as follows:

Traversing child nodes
function Cascade (FN, item, args) {
if (FN (item, args, 1)!= false) {
if (item. ChildNodes!= null && item. Childnodes.length > 0) {
var cs = Item. ChildNodes;
for (var i = 0, len = cs.length i < len; i++) {
Cascade (FN, cs[i], args);
}
}
}
}
Bubbles of Ancestors
Function Bubble (FN, item, args) {
var p = item.parent;
while (p) {
if (FN (p, args, 0) = = False) {
Break
}
p = p.parent;
}
}



Find the node will also trigger the check this callback function to determine the status of the current node, detailed see the following code in the comments section should be more clear, describing the process


Copy Code code as follows:
Function Check (item, state, type) {
var pstate = item.checkstate;//Current status
if (type = = 1) {
Item.checkstate = state;//If you are traversing a child node, what is the parent,
}
Else {//trace, this is a bit more complicated.
Var CS = Item. ChildNodes; Gets all child nodes of the current node
var l = cs.length;
var ch = true;/is not intermediate state semi-select
for (var i = 0; i < L; i++) {
if (= = 1 && cs[i].checkstate != 1) | | state = = 0 && cs[i].checkstate!= 0) {
ch = false;
break;//His child nodes as long as one is not selected, then he is half selected
}
}
if (ch) {
Item.checkstate = state;//is not half selected, then what is the child node?

Else {
Item.checkstate = 2;//semi-selected
}
}
//change Show if the node has been exported and its status is different, the display of the change Checkbxo
if (item.render && pstate!= item.checkstate) {
var et = $ ("#" + ID + "_" + item.id + "_CB");
if (et.length = 1) {
et.attr ("src", Dfop.cbiconpath + dfop.icons[item.checkstate]);
}
}
}



So far the main function of our tree has been fully realized. The other is to expose some methods, etc., you can see the code, the example exposes the two currently selected all nodes, another current node.

We can use the following Web site to view the example of the text, selected misspelled, we Haihan! Windows Azure deployment or bother to modify the 3500+ node once loaded, you can click the root node of the full selection to see the speed

Http://jscs.cloudapp.net/ControlsSample/BigTreeSample

Asynchronous loading, on-demand loading is also very common, using the SQL Azure server in the US ing, so it may be asynchronous a bit slow, local data source that is instantaneous

Http://jscs.cloudapp.net/ControlsSample/TreeAsnySample

FAQ:

1: How do I set a different icon for each node?

Reply:

In fact, do not need to expand, the support itself, just did not explain it, let's take a look at this code? Is there such a thing in the Buildnode method?
if (nd.classes) {Cs.push (nd.classes);}

Property classes can be set in the node's data structure, which is added to the node as a special CSS Class for the node. So using this, you can set the icon for the node

Then you can write a style

What's the final effect?

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.