源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

打造基于jQuery的高性能TreeView(asp.net)

  • 时间:2022-01-06 07:05 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:打造基于jQuery的高性能TreeView(asp.net)
根据我的项目实践情况,主要是几个关键点: 1:支持静态的树,即一次性将全部数据加载到客户端。 2:异步树,即一次只加载一级或若干级节点,子节点可以异步加载数据。 3:Checkbox树(可能是静态树也可能是异步树),用于选择(如选择组织机构,选择数据字典项)等,最好是能够支持节点级联(这个是难点) 4:能够承载大数据量,并性能表现优异 5:能够在主流浏览器中运行良好 那我要打造的TreeView就是为了实现这个5个主要指标的。 先来看下效果图 [img]http://files.jb51.net/upload/201102/20110223123822197.png[/img] 上图是中国行政区域的数据树,总共得节点是3500+。 那么我们要开工了; [b]1:第一个确定的节点Dom结构(即用什么样的HTML来构建节点)[/b] [list] [*]比较土的是table套table的(样式上好控制,但是大数据量,和层次较深的树,这种结构肯定顶不住的) [/*][*]还有一种是比较新鲜的UL套LI的方式,这是现下很多书采取的方式如Jquery.treeview就是采用的这种格式,好处比较明显就是结构简洁明了, 而且在不支持Js的浏览器上,同样也能呈现出树的形状(这种情况其实咱可以忽略),但是Jquery.treeview的节点在IE下,特别是IE6下无法被内部元素撑开,(IE7,8当达到一定深度时无法撑开),请奇怪的现象(我猜测是因为使用padding来做缩进,margin-left:负值来控制图标位置有关,但是修改起来难度也较大),在这种情况下书会变形(Jquery.treeview)就有这种问题,只能通过设置节点的width来解决。 [/*][/list] [img]http://files.jb51.net/upload/201102/20110223123822849.png[/img] JQuery.treeview的节点结构 [img]http://files.jb51.net/upload/201102/20110223123822763.png[/img] Jquery.TreeView  IE6 下 展开第三级即出现错位 [img]http://files.jb51.net/upload/201102/20110223123822726.png[/img] IE8下展开到第5级 [list] [*]还有一些是div套table的方式,CSDN的导航树就是这种,是种折中的方法(节点也不算太复杂,而且CSS也比较好写),如下图所示 [img]http://files.jb51.net/upload/201102/20110223123822671.png[/img] [/*][/list]       而我采用的也是第二种方式,但是缩进采用了填空的方式,即缩进的位置用空白的图片填充来避免Jquery.treeview的问题 [img]http://files.jb51.net/upload/201102/20110223123822175.png[/img] 我的树节点结构 确定了节点的HTML我们就可以来写CSS了。有了效果图,有个节点结构接着就编写CSS了 下面是CSS的完整代码
[url=http://www.1sucai.cn/upload/201102/20110223123822528.png][img]http://files.jb51.net/upload/201102/20110223123822370.png[/img] [/url] 这就是那个+号带line的样式 css中所用到的所有图片 [url=http://www.1sucai.cn/upload/201102/20110223123822128.gif][img]http://files.jb51.net/upload/201102/20110223123822737.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123822628.gif][img]http://files.jb51.net/upload/201102/20110223123822954.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123822582.gif][img]http://files.jb51.net/upload/201102/20110223123822125.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123822962.gif][img]http://files.jb51.net/upload/201102/20110223123822365.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123822608.gif][img]http://files.jb51.net/upload/201102/20110223123823757.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123823625.gif][img]http://files.jb51.net/upload/201102/20110223123823304.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123823864.gif][img]http://files.jb51.net/upload/201102/20110223123823322.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123823334.gif][img]http://files.jb51.net/upload/201102/20110223123823284.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123823265.gif][img]http://files.jb51.net/upload/201102/20110223123823269.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123823719.gif][img]http://files.jb51.net/upload/201102/20110223123823254.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123823281.gif][img]http://files.jb51.net/upload/201102/20110223123823496.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123823484.gif][img]http://files.jb51.net/upload/201102/20110223123823294.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123823461.gif][img]http://files.jb51.net/upload/201102/20110223123823773.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123823752.gif][img]http://files.jb51.net/upload/201102/20110223123823833.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123823153.gif][img]http://files.jb51.net/upload/201102/20110223123823379.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123823797.gif][img]http://files.jb51.net/upload/201102/20110223123823462.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123823846.gif][img]http://files.jb51.net/upload/201102/20110223123823773.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123823277.gif][img]http://files.jb51.net/upload/201102/20110223123823666.gif[/img] [/url] [url=http://www.1sucai.cn/upload/201102/20110223123823624.gif][img]http://files.jb51.net/upload/201102/20110223123823948.gif[/img] [/url] [b]2:确定数据结构 [/b]
[url=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 {// 上溯 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]); } } } //遍历子节点 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); } } } } //冒泡的祖先 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") { // +号需要展开 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")) { //- 号需要收缩 $(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")) // 点击了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) { //遍历 cascade(check, item, s); //上溯 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; } //获取所有选中的节点的Value数组 $.fn.getTSVs = function() { if (this[0].t) { return this[0].t.getSelectedValues(); } return null; } //获取所有选中的节点的Item数组 $.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);
第一步:自然是所有Jquery的控件的第一步都是搭这个架子,兼容JQuery和$避免闭包,避免和其他类库冲突,接受一个参数(是个对象) 那第二步:给控件加一些参数默认参数,同时能调用方法$.extend让最终调用时的参数覆盖默认的(如果没有则使用默认)
[url=http://jscs.cloudapp.net/ControlsSample/BigTreeSample]http://jscs.cloudapp.net/ControlsSample/BigTreeSample[/url]  异步加载,按需加载的情况也是非常常用的,使用的是SQL Azure服务器在美国ing,所以可能异步有点慢,本地数据源那是瞬间的 [url=http://jscs.cloudapp.net/ControlsSample/TreeAsnySample]http://jscs.cloudapp.net/ControlsSample/TreeAsnySample[/url] FAQ: [i]1:如何设置每个节点不同的图标?[/i] 回答: 其实不用扩展,本身就支持,只是没有说明而已,我们来看一下这个代码吧?在BuildNode方法中有这么一句?       if (nd.classes) { cs.push(nd.classes); } 在节点的数据结构中可以设置属性classes ,该属性将作为节点特殊的Css Class 添加到节点上。那么利用这点,就可以设置节点的图标了 [img]http://files.jb51.net/upload/201102/20110223123823652.png[/img] 然后就是编写一个Style 即可 [img]http://files.jb51.net/upload/201102/20110223123823921.png[/img] 最后来看下效果吧? [img]http://files.jb51.net/upload/201102/20110223123823538.png[/img]
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部