使用jquery制作动态加载型菜单

时间:2021-08-09 12:00:06

  为了提升后台管理系统的加载。决定对后台的菜单进行动态加载。具体实现方式和我上一篇文章差不多。不过我把js代码进行了封装。

css:

.menu {position:relative;}   
.menu ul {position:absolute; margin:0; padding:0; list-style:none; white-space:nowrap; background:#f1f8fe; border:1px solid #fff; padding:10px 0;
-o-border-radius: 8px;
-ms-border-radius: 8px; 
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
-o-box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.5); 
-ms-box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.5); 
-moz-box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.5);
-webkit-box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.5); 
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.5); 
}
.menu ul ul {display:none; left:100%; margin-top:-33px; margin-left:-5px;}
.menu li {margin:0; padding:0; list-style:none; display:inline-block; display:inline;line-height:20px;}
.menu a {display:block; font:normal 11px verdana,arial,sans-serif; color:#000; line-height:22px; text-decoration:none; padding:0 20px 0 10px;}
.menu li a.fly {background: url(/static/images/widget/arrow-right.gif) no-repeat right top;}
.menu li:hover > a {background-color:#c60; color:#fff;}

js:

/*
 * 添加channel_tree
 * 害怕影响后面代码,添加作用域,保证模块的单独性。
 * 在页面dom加载完之后再执行代码。
 * */
window.onload = function() {
    (function() {
        var data,
            uniqueName;
        //添加元素唯一标识,解耦。主要是为了兼容添加碎片的代码
        if($("[name='channel_select_django_btn']").length != 0)
            uniqueName = "[name = 'channel_select_django_btn']";
        else
            uniqueName = "span[name = 'channel_select_btn']";
        //因为在添加模板的时候需要添加无父对象的字段。
        var hastemplate = document.location.pathname.match(/template/);
        var url = "/api/channel_tree/";
        $.getJSON(url, function(json) {
            data = eval('(' + json.data + ')');
            if(hastemplate)
                data = [{"id": "","name": "无父对象","have_children": false}].concat(data);
        })
        $(uniqueName).bind("click", function() {
            if($(uniqueName + " > .menu").length == 0)
                Menu.init();
            else
               $(uniqueName + " > .menu").show();
        })
        //绑定document点击事件
        $(document).click(function(e) {
            var element = event.target;
            if($(uniqueName + " > .menu").length && jQuery.contains($(uniqueName)[0],element)){}else
                $(uniqueName + " > .menu").hide();
        })
        var Menu = {
            init: function() {
                var menuNode = $("<div class='menu' style='position: absolute; height: 440px;'></div>"),
                    ul = $("<ul></ul>");
                _this = this;
                this.arr = [0];
                $(uniqueName).append(menuNode);
                menuNode.append(ul);
                for(var i=0; i<data.length; i++){
                    $(".menu > ul").append(this.createANode(data[i]))
                }
            },
            createANode: function(nodeInfo, rootNode) {
                var icon_name,
                    nodeId;
                if (nodeInfo.have_children == false) {
                    var parentNode = $('<li class=""></li>');
                    var html = '<a sid = ' + nodeInfo.id + '>' + nodeInfo.name + '</a>';
                    parentNode.append(html);
                } else {
                    var parentNode = $('<li class=""></li>'),
                        html = '<a sid = ' + nodeInfo.id + ' class="fly">'+ nodeInfo.name + '</a><ul style="display: none;"></ul>';
                    parentNode.append(html);
                }
                $("a", parentNode).hover(
                    function(e) {
                        e.stopPropagation();
                        nodeId = parseInt(e.target.getAttribute("sid"));
                        var dataUrl = "/api/channel_tree/" + nodeId + "/";
                        if(!_this.contains(nodeId, _this.arr) && nodeId)
//                    if(localStorage.getItem(dataUrl)) {
//                        var obj = eval('(' + localStorage.getItem(dataUrl) + ')');
//                        var nodes = eval('(' + obj.data + ')');
//                        for(var j=0; j<nodes[0].children.length; j++) {
//                            _this.createANode(nodes[0].children[j], parentNode);
//                        }
//                    }
                            $.ajax({
                                type: "get",
                                url: dataUrl,
                                success: function(json) {
                                    localStorage.setItem(dataUrl, json);
                                    var obj = eval('(' + json + ')');
                                    var nodes = eval('(' + obj.data + ')');
                                    for(var j=0; j<nodes[0].children.length; j++) {
                                        _this.createANode(nodes[0].children[j], parentNode);
                                    }
                                }
                            })
                        if($(this).parent().children('ul'))
                            $(this).parent().children('ul').show();
                        $(this).parent().siblings().find('ul').hide();
                    },
                    function() {
                        $(this).siblings().children().find('ul').hide();
                        $(this).parent().siblings().find('ul').hide();
                    }
                )
                $("a", parentNode).click(function(e) {
                    e.stopPropagation();
                    var val = $(this).html();
                    $(uniqueName).find(".menu").hide();
                    $(uniqueName + " > input").val(val);
                    $("[name = 'channel']").val(nodeId);
                    if(uniqueName == "[name = 'channel_select_django_btn']") {
                        var sid = $(this).attr("sid")
                        alert(sid);
                        $(uniqueName).attr("sid", sid);
                    }
                })
                if(rootNode) {
                    rootNode.children().last().append(parentNode);
                } else
                    return parentNode;
            },
            contains: function(nodeId, arr) {
                for(var key in arr)
                    if(nodeId == arr[key])
                        return true;
                _this.arr.push(nodeId);
                return false;
            }
        }
     })()
}

 

第一份数据:

{
"status": 0,
"data": "[{\"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}]"
}

使用jquery制作动态加载型菜单