這次在原先html自定義垂直導航菜單的基礎上做了比較大的改動:
1、去掉了font-awesome圖標,上級菜單右邊的箭頭是自己用css寫的,具體參考《css三角箭頭》。
2、去掉了初始化時候打開的菜單的屬性openIndex(考慮到多級菜單子菜單的打開方式,暫時去掉),添加了superLevel(默認是0,即當前添加的不論是一個JSArray還是JSObject,我們都將作為一級菜單(0+1)處理。)
3、將二級導航變為多級導航菜單,可以無限添加子菜單,你只需要在treeMenu.css的合適的地方添加或者修改自己的每個級別的css樣式即可,這里我默認處理了三級菜單的樣式。
3、在TreeMenu中添加圓角邊框,添加鼠標滑過后的菜單Hover樣式。
看下效果圖(個人覺得比較素雅,完全有自己的元素在里面,修改起來很方便):
用到的css:
treeMenu.css
用到的js:
jquery-1.9.1.js
json2.js
checkutil.js(自己隨手寫的一個檢測js對象類型的工具)
treeMenu.js(※※※※※這個才是重點 - -)
上代碼(源碼地址:http://files.cnblogs.com/files/wrcold520/TreeMenu.zip,html、css、js中的注釋很詳盡,如果有不對的地方,歡迎留言,3Q!!!):
html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="css/treeMenu.css" /> <script type="text/javascript" src="js/json2.js"></script> <script type="text/javascript" src="js/jquery-1.9.1.js"></script> <script type="text/javascript" src="js/checkutil.js"></script> <script type="text/javascript" src="js/treeMenu.js"></script> <title></title> </head> <style> body { background: lightgray; } .TreeMenuList>div { margin: 5px; } .TreeMenuList { /**flexbox兼容**/ display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */ display: -moz-box; /* OLD - Firefox 19- (doesn't work very well) */ display: -ms-flexbox; /* TWEENER - IE 10 */ display: -webkit-flex; /* NEW - Chrome */ display: flex; /**flexbox兼容**/ -webkit-box-orient: horizontal; -webkit-flex-direction: row; -moz-flex-direction: row; -ms-flex-direction: row; -o-flex-direction: row; flex-direction: row; } </style> <body> <div class="TreeMenuList"> <div id="TreeMenu01"></div> <div id="TreeMenu02"></div> </div> <div class="TreeMenuList"> <div id="TreeMenu03"></div> <div id="TreeMenu04"></div> </div> </body> <script> var menus01 = [{ name: "menu1", href: "", subMenus: [{ name: "menu1.1", href: "", subMenus: [{ name: "menu1.1.1", href: "#menu1.1.1", }, { name: "menu1.1.2", href: "#menu1.1.2" }] }, { name: "menu1.2", href: "#menu1.2", subMenus: [{ name: "menu1.2.1", href: "#menu1.2.1" }, { name: "menu1.2.2", href: "#menu1.2.2" }] }, { name: "menu1.3", href: "#menu1.3", subMenus: [{ name: "menu1.3.1", href: "#menu1.3.1" }, { name: "menu1.3.2", href: "#menu1.3.2" }] }] }, { name: "menu2", href: "", subMenus: [{ name: "menu2.1", href: "", subMenus: [{ name: "menu2.1.1", href: "#menu2.1.1" }, { name: "menu2.1.2", href: "#menu2.1.2" }] }, { name: "menu2.2", href: "#", subMenus: [{ name: "menu2.2.1", href: "#menu2.2.1" }, { name: "menu2.2.2", href: "#menu2.2.2" }] }, { name: "menu2.3", href: "#menu2.3", subMenus: [{ name: "menu2.3.1", href: "#menu2.3.1" }, { name: "menu2.3.2", href: "#menu2.3.2" }] }] }, { name: "menu3", href: "", subMenus: [{ name: "menu3.1", href: "", subMenus: [{ name: "menu3.1.1", href: "#menu3.1.1" }, { name: "menu3.1.2", href: "#menu3.1.2" }] }, { name: "menu3.2", href: "#", subMenus: [{ name: "menu3.2.1", href: "#menu3.2.1" }, { name: "menu3.2.2", href: "#menu3.2.2" }] }, { name: "menu3.3", href: "#menu3.3", subMenus: [{ name: "menu3.3.1", href: "#menu3.3.1" }, { name: "menu3.3.2", href: "#menu3.3.2" }] }] }];
var menus02 = JSON.stringify(menus01); var menus03 = { name: "menu1", href: "", subMenus: [{ name: "menu1.1", href: "", subMenus: [{ name: "menu1.1.1", href: "#menu1.1.1", }, { name: "menu1.1.2", href: "#menu1.1.2" }] }, { name: "menu1.2", href: "#menu1.2", subMenus: [{ name: "menu1.2.1", href: "#menu1.2.1" }, { name: "menu1.2.2", href: "#menu1.2.2" }] }, { name: "menu1.3", href: "#menu1.3", subMenus: [{ name: "menu1.3.1", href: "#menu1.3.1" }, { name: "menu1.3.2", href: "#menu1.3.2" }] }] };
var menus04 = JSON.stringify(menus03);
var config01 = { treeMenuId: "#TreeMenu01", superLevel: 0, multiple: true, }; var config02 = { treeMenuId: "#TreeMenu02", superLevel: 0, multiple: false }; var config03 = { treeMenuId: "#TreeMenu03", superLevel: 0, multiple: true } var config04 = { treeMenuId: "#TreeMenu04", superLevel: 0, multiple: false } treeMenu.init(menus01, config01); treeMenu.init(menus02, config02); treeMenu.init(menus03, config03); treeMenu.init(menus04, config04); </script> </html>
treeMenu.css:
.TreeMenu { /** TreeMenu整體樣式 **/ font-family: "edwardian script itc"; min-width: 300px; } .TreeMenu> .MenuBox { /** 不能選擇文本 **/ cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; } .TreeMenu> .Radius { /** 圓角邊框,添加圓角半徑的上下Padding **/ background: white; border: 1px solid darkgray; border-radius: 8px; -webkit-border-radius: 8px; -moz-border-radius: 8px; padding-top: 8px; padding-bottom: 8px; } .TreeMenu ul, .TreeMenu ol { /** 去掉TreeMenu下面ul/ol的默認樣式 **/ list-style: none; margin: 0; padding: 0; } .TreeMenu .MenuName { /** 所有菜單名稱的樣式 ,flex布局,垂直居中,兩端對齊**/ align-items: center; /**flexbox兼容**/ display: flex; display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */ display: -moz-box; /* OLD - Firefox 19- (doesn't work very well) */ display: -ms-flexbox; /* TWEENER - IE 10 */ display: -webkit-flex; /* NEW - Chrome */ /**flexbox兼容**/ flex-direction: row; -webkit-box-orient: horizontal; -webkit-flex-direction: row; -moz-flex-direction: row; -ms-flex-direction: row; -o-flex-direction: row; justify-content: space-between; -webkit-justify-content: space-between; } .TreeMenu .Level-1 .MenuName { /** 一級菜單菜單名稱樣式 **/ color: mediumpurple; font-size: 20px; padding: 8px 10px 8px 10px; } .TreeMenu .Level-2 .MenuName { /** 二級菜單菜單名稱樣式 **/ color: darkred; font-size: 18px; padding: 8px 10px 8px 20px; } .TreeMenu .Level-3 .MenuName { /** 三級菜單菜單名稱樣式 **/ color: darkslategrey; font-size: 16px; padding: 8px 10px 8px 30px; } .TreeMenu .MenuName:hover { /** 鼠標滑過菜單樣式 **/ background: #E3E3E3; font-weight: 600; } .TreeMenu .Level-1 { /** 一級菜單li **/ border-bottom: 1px solid gainsboro; } .TreeMenu .Level-1:last-child { /** 最后一個一級菜單左下、右下圓角 **/ border-bottom: 0px; } .TreeMenu .Level-2 { /** 二級菜單li **/ border-top: 1px solid gainsboro; margin: 0px 10px; } .TreeMenu .Level-3 { /** 三級菜單li **/ border-top: 1px solid gainsboro; margin: 0px 20px; } .TreeMenu .TreeArrowDown { /** 右邊三角箭頭的樣式 **/ border-left: 6px solid transparent; border-right: 6px solid transparent; border-top: 10px solid darkgray; display: inline-block; width: 0px; height: 0px; transition: all 0.5s ease; -webkit-transition: all 0.5s ease; -moz-transition: all 0.5s ease; -ms-transition: all 0.5s ease; -o-transition: all 0.5s ease; } .TreeMenu .Level.active .TreeArrowDown.rotate { /** 選中當前菜單右邊三角箭頭逆時針旋轉180度 **/ -webkit-transform: rotate(-180deg); -moz-transform: rotate(-180deg); -ms-transform: rotate(-180deg); -o-transform: rotate(-180deg); transform: rotate(-180deg); } .TreeMenu .Level .MenuBox { /** 默認不顯示所有下級菜單 **/ display: none; } .TreeMenu a, .TreeMenu a:link, .TreeMenu a:hover, .TreeMenu a:active, .TreeMenu a:visited { /** 去掉a標簽樣式 **/ color: inherit; text-decoration: none; }
treeMenu.js:
/** * //1、menu01: JS Array * var menus01 = [{ * name: "menu1", * href: "", * subMenus: [{ * name: "menu1.1", * href: "", * subMenus: [{ * name: "menu1.1.1", * href: "#menu1.1.1", * }, { * name: "menu1.1.2", * href: "#menu1.1.2" * }] * }, * ....//省略若干子菜單 * ] * }, * ...//省略若干菜單 * ]; * * //2、menu02:JSON Array * var menus02 = JSON.stringify(menus01); * * //3、menu03: JS Object * var menus03 = { * name: "menu1", * href: "", * subMenus: [{ * name: "menu1.1", * href: "", * subMenus: [{ * name: "menu1.1.1", * href: "#menu1.1.1", * }, { * name: "menu1.1.2", * href: "#menu1.1.2" * }] * }, { * name: "menu1.2", * href: "#menu1.2", * subMenus: [{ * name: "menu1.2.1", * href: "#menu1.2.1" * }, { * name: "menu1.2.2", * href: "#menu1.2.2" * }] * }, { * name: "menu1.3", * href: "#menu1.3", * subMenus: [{ * name: "menu1.3.1", * href: "#menu1.3.1" * }, { * name: "menu1.3.2", * href: "#menu1.3.2" * }] * }] * }; * * //4、JSON object * var menus04 = JSON.stringify(menus03); * * var config01 = { * treeMenuId: "#TreeMenu01", //required * superLevel: 0, //optional * multiple: true, //optional * }; * * var config02 = { * treeMenuId: "#TreeMenu02", //required * superLevel: 0, //optional * multiple: false //optional * }; * * var config03 = { * treeMenuId: "#TreeMenu03", //required * superLevel: 0, //optional * multiple: true //optional * } * * var config04 = { * treeMenuId: "#TreeMenu04", //required * superLevel: 0, //optional * multiple: false //optional * } * treeMenu.init(menus01, config01); * treeMenu.init(menus02, config02); * treeMenu.init(menus03, config03); * treeMenu.init(menus04, config04); * * @author DarkRanger * see more https://coding.net/u/wrcold520/p/TreeMenu-Simple-Tree-Menu-js/git/tree/master/TreeMenu * */ ! function($, JSON, checkutil) { "use strict"; var treeMenu = {}; treeMenu.name = "MenuTree-Simple Left Navigation Tree Menu"; treeMenu.version = "version-1.0"; treeMenu.author = "DarkRanger"; treeMenu.email = "15934179313@163.com"; treeMenu.url = "https://coding.net/u/wrcold520/p/TreeMenu-Simple-Tree-Menu-js/git/tree/master/TreeMenu"; treeMenu.config = function() {}; treeMenu.init = function(datas, config) { var menuConfig = new treeMenu.config(); if(checkutil.isUndefined(datas)) { console.log("The function treeMenu.init() doesn't have the parameter 'datas' that means the treeMenu has no Datas!"); return; } else { //JS Object or JS Array if(checkutil.isArray(datas)) { menuConfig.menus = datas; } else if(checkutil.isObject(datas)) { menuConfig.menus = [datas]; } //JSONString else if(checkutil.isString(datas)) { var menuObj; try { var menuJson = JSON.parse(datas); if(checkutil.isArray(menuJson)) { menuObj = menuJson; } else if(checkutil.isObject(menuJson)) { menuObj = [menuJson]; } menuConfig.menus = menuObj; } catch(e) { throw new Error(e); } } if(checkutil.isUndefined(menuConfig.menus)) { console.warn("datas is not jsonString or JS Object or JS Array, configure failed!!!"); return; } } if(checkutil.isUndefined(config)) { console.log("The function treeMenu.init() doesn't have the parameter 'config' that means the treeMenu has no event!"); } else { if(checkutil.isUndefined(config.treeMenuId)) { console.warn("Your TreeMenu config has not key['treeMenuId'], configure failed!!!\nPlease configure your unique treeMenu by treeMenuId!"); return; } else if($(config.treeMenuId).length == 0) { console.warn("Cannot find your treeMenu[id: " + config.treeMenuId + "], configure failed!!! "); return; } else { menuConfig.treeMenuId = config.treeMenuId; } if(checkutil.isUndefined(config.superLevel)) { console.warn("Your config has not key['superLevel'], default value is 0 that means you your datalist'superlevel is 0!"); menuConfig.superLevel = 0; } else if(!checkutil.isNumber(config.superLevel)) { console.warn("Your config's parameter['superLevel'] shoule be a Number, configure failed!"); return; } else { menuConfig.superLevel = config.superLevel; } if(checkutil.isUndefined(config.multiple)) { console.warn("Your config has not key['multiple'], default value is false that means you could open one spMenu at most at the same time!"); menuConfig.multiple = false; } else { menuConfig.multiple = config.multiple; } menuConfig.multiple = config.multiple; } genDomTree(menuConfig); initEvent(menuConfig); } /** * 生成dom樹 * @param {Object} menuConfig */ function genDomTree(menuConfig) { var $treeMenu = $(menuConfig.treeMenuId); var menus = menuConfig.menus; var multiple = menuConfig.multiple; var hasTreeMenuClass = $treeMenu.hasClass("TreeMenu"); if(hasTreeMenuClass === false) { $treeMenu.addClass("TreeMenu"); } var firstLevel = menuConfig.superLevel; eachMenusDom($treeMenu, menus, firstLevel); } /** * 遞歸生成dom樹 * @param {Object} superEle 在哪個元素下添加子元素 * @param {Object} subMenus 子元素的集合 JS Array * @param {Object} superLevel 上級元素的等級 */ function eachMenusDom(superEle, subMenus, superLevel) { var level = superLevel + 1; var ulBox01 = $("<ul>", { "class": "MenuBox MenuBox-" + level+" Radius", }); $.each(subMenus, function(i, menu) { var liItem = $("<li>", { "class": "Level Level-" + level, }); var menuNameDiv = $("<div>", { "class": "MenuName", }); var menuLink = $("<a>"); var hasHref = menu.href && $.trim(menu.href).length > 0; if(hasHref === true) { menuLink.attr("href", menu.href); } var hasName = menu.name && menu.name.length > 0; if(hasName === true) { menuLink.text(menu.name); } menuLink.appendTo(menuNameDiv); menuNameDiv.appendTo(liItem); liItem.appendTo(ulBox01); ulBox01.appendTo(superEle); var subMenus = menu.subMenus; if(subMenus && checkutil.isArray(subMenus) && subMenus.length > 0) { var arrowDownDiv = $("<div>", { "class": "TreeArrowDown" }); arrowDownDiv.appendTo(menuNameDiv); eachMenusDom(liItem, subMenus, level); } }); } /** * 初始化點擊事件 * @param {Object} menuConfig */ function initEvent(menuConfig) { $(menuConfig.treeMenuId + " .MenuName").on("click", function() { var $arrow = $(this).find(".TreeArrowDown"); var $menuBox = $(this).next(); var $menuItem = $(this).parent(); $menuBox.slideToggle(); $arrow.toggleClass("rotate"); $menuItem.toggleClass("active"); if(menuConfig.multiple === false) { var $brothers = $menuItem.siblings(); $brothers.find(".MenuBox").slideUp(); $brothers.find(".TreeArrowDown").removeClass("rotate"); $brothers.removeClass("active"); } }); } window.treeMenu = treeMenu; }($, JSON, checkutil);
附上源碼:TreeMenu.zip