基于jquery来制作动态加载树

  最近更新的后台树节点的加载方式。因为以前用的是jquery-treeview插件。 但是上网查了下资料,发现用它来实现树节点的动态加载还是挺麻烦的。于是我自己写了个动态加载的方式。下面贴代码。

css样式:

.treeview li{background: url(static/images/treeview-default-line0.gif) 0 0 no-repeat; margin: 0; padding: 4px 0pt 4px 16px; margin-left:5px;}
.treeview li img{ margin-right:5px; margin-left:5px;}
.hitarea{background: url(static/images/treeview-black.gif) -64px -25px no-repeat; height: 16px; width: 16px; margin-left: -16px; float: left; cursor: pointer;}
.expandable-hitarea{background-position: -80px -3px;}

js代码:

for(var i=0; i<data.length; i++){
    $("#tree").append(createANode(data[i]))
}
function createANode(nodeInfo, rootNode) {
    var icon_name;
    if(nodeInfo.type == 0) {
        icon_name = 'icon1.png';
    }
    else if(nodeInfo.type == 2){
        icon_name = 'icon3.gif';
    }
    else{
        icon_name = 'icon2.png';
    }

    var tree_url = '/admin/web/channel/home/' + nodeInfo.id + '/';
    var icon_url = '/static/images/' + icon_name;

    if (nodeInfo.have_children == false) {
        var parentNode = $('<li></li>');
        var html = '<a href= " ' + tree_url + '" target = "django_channel"> ' +'<img  src = "' + icon_url +'" >' + nodeInfo.name + '</a>';
        parentNode.append(html);
    } else {
        var parentNode = $('<li class="expandable"></li>');
        var html = ' <div class="hitarea expandable-hitarea"></div><a href = " ' + tree_url + '" target = "django_channel">' + '<img  src = "' + icon_url + '" >'+ nodeInfo.name + '</a><ul ></ul>';
        parentNode.append(html);
        var nodeId = nodeInfo.id;
        //这里是绑定树节点的展开事件。
        parentNode.find("div").bind("click", function(event) {
                if($(this).attr("class")=="hitarea expandable-hitarea") {
                    $(this).removeClass().addClass("hitarea collapsable-hitarea").parent().removeClass().addClass("collapsable").find("ul").show();
                } else {
                    $(this).removeClass().addClass("hitarea expandable-hitarea").parent().removeClass().addClass("expandable").find("ul").hide(); 
                }
            })
        
        parentNode.bind("click", function(event) {
           event.stopPropagation();   
           var dataUrl = "api/channel_tree/" + nodeId + "/";
           $.ajaxSettings.async = false;
           $.ajax({
               type: "get",
               url: dataUrl,
               success: function(json) {
                   var obj = eval('(' + json + ')');
                   var nodes = eval('(' + obj.data + ')');
                   for(var j=0; j<nodes[0].children.length; j++) {
                       createANode(nodes[0].children[j], parentNode);
                   }
               }
           })        
           parentNode.unbind("click");
        })
        
    }
    if(rootNode) {
        rootNode.children().last().append(parentNode);
    } else
        return parentNode;
}

本来想用事件委托来做事件绑定的,但是发现用事件委托时不可行的。所以别吐槽这种绑定时间的方式太费性能。

后台把第一层数据通过模板写在页面中

数据:

[{"children": [], "name": "\u72d0\u9996", "parent": -1, "have_children": true, "desc": "", "type": 0, "id": 1, "is_subject": false}, {"children": [], "name": "\u65b0\u95fb", "parent": -1, "have_children": true, "desc": null, "type": 0, "id": 2, "is_subject": false}, {"children": [], "name": "\u4f53\u80b2", "parent": -1, "have_children": true, "desc": null, "type": 0, "id": 3, "is_subject": false}, {"children": [], "name": "\u5a31\u4e50", "parent": -1, "have_children": true, "desc": null, "type": 0, "id": 4, "is_subject": false}, {"children": [], "name": "\u8d22\u7ecf", "parent": -1, "have_children": true, "desc": null, "type": 0, "id": 5, "is_subject": false}, {"children": [], "name": "\u79d1\u6280", "parent": -1, "have_children": true, "desc": null, "type": 0, "id": 7, "is_subject": false}, {"children": [], "name": "\u519b\u4e8b", "parent": -1, "have_children": true, "desc": null, "type": 0, "id": 8, "is_subject": false}, {"children": [], "name": "\u661f\u5ea7", "parent": -1, "have_children": true, "desc": null, "type": 0, "id": 9, "is_subject": false}, {"children": [], "name": "\u56fe\u5e93", "parent": -1, "have_children": true, "desc": null, "type": 0, "id": 10, "is_subject": false}, {"children": [], "name": "\u6d4b\u8bd5", "parent": -1, "have_children": true, "desc": null, "type": 0, "id": 11, "is_subject": false}, {"children": [], "name": "\u5973\u4eba", "parent": -1, "have_children": true, "desc": null, "type": 0, "id": 326, "is_subject": false}, {"children": [], "name": "\u5176\u5b83", "parent": -1, "have_children": true, "desc": null, "type": 0, "id": 328, "is_subject": false}, {"children": [], "name": "\u6e20\u9053", "parent": -1, "have_children": true, "desc": null, "type": 0, "id": 561, "is_subject": false}, {"children": [], "name": "\u65e0\u7ebf", "parent": -1, "have_children": true, "desc": null, "type": 0, "id": 564, "is_subject": false}, {"children": [], "name": "\u5fae\u535a", "parent": -1, "have_children": false, "desc": null, "type": 0, "id": 565, "is_subject": false}, {"children": [], "name": "\u5e7f\u544a", "parent": -1, "have_children": true, "desc": null, "type": 0, "id": 577, "is_subject": false}].

之后的数据通过绑定点击事件来获取接口数据。

给出第一个节点的数据:

{

"status": 0,

"data": "[{\"children\": [{\"children\": [], \"name\": \"\\u6b63\\u6587\\u9875\\u63a8\\u8350\", \"parent\": 1, \"have_children\": false, \"desc\": \"\", \"type\": 1, \"id\": 465, \"is_subject\": false}, {\"children\": [], \"name\": \"UC\", \"parent\": 1, \"have_children\": false, \"desc\": \"\", \"type\": 1, \"id\": 588, \"is_subject\": false}], \"name\": \"\\u72d0\\u9996\", \"parent\": -1, \"have_children\": true, \"desc\": \"\", \"type\": 0, \"id\": 1, \"is_subject\": false}]"

}。

具体生成数据方式不给出了。