在上一篇中我简单写了个html自定义垂直导航菜单,缺点很明显,里面的数据是固定死的,不能动态更改数据。
这里我重写了一个修改版的垂直二级导航菜单,将原先的menuBox.init(config);修改为menuBox.init(config, dataObj);,这里的dataObj就是要传入的菜单的数据,可以传入的类型有JSONArray、JSArray、JSONObject、JSObject,其实JSONObject就是JSONArray中的一个元素,JSObject也是JSArray中的一个元素。
先上效果图:
怎么样,还可以吧(作为一名菜鸡,做个二级菜单不容易,吹一波不过分),顺便附上源码:menuBox1.1.zip。
你完全可以按照你的需求修改对应的css样式,打造属于你自己的二级菜单。
上代码:
JSObject
{ name: "spMenu1", iconClasses: "fa fa-chrome", subMenus: [{ name: "subMenu11", url: "#" }, { name: "subMenu12", url: "#" }, { name: "subMenu13", url: "#" }, { name: "subMenu14", url: "#" }] }
这里需要解释下:
上面的js就是一级菜单的JSObject元素(当然,你也可以转化为标准的json字符串格式),属性分别是:
name:当前一级菜单的名称
iconClasses:在效果图中大家可以看到,每个一级菜单前面是有图标的,这里使用的是fontawesome(旧版本,你可以使用新版本,将font-awesome文件夹替换掉就可以使用新的class样式图标了),这里的iconClasses就是<i></i>的class,你可以添加属于自己的图标,如果你想添加书签的图标,你可以传入字符串"fa fa-bookmark",挺简洁的。
subMenus:这个就是二级菜单的数组集合了,这里默认二级菜单没有图标,只有名称和url(点击跳转或者切换内容区域的url)
html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="font-awesome/css/font-awesome.css" /> <link rel="stylesheet" href="css/menuBox-1.1.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/menuBox-1.1.js"></script> <title></title> </head> <style> .menuBox { margin: 20px; } </style> <body> <div id="menuBox01" class="menuBox"> </div> <div id="menuBox02" class="menuBox"> </div> <div id="menuBox03" class="menuBox"> </div> <div id="menuBox04" class="menuBox"> </div> </body> <script> var dataObj01 = [{ name: "spMenu1", iconClasses: "fa fa-chrome", subMenus: [{ name: "subMenu11", url: "#" }, { name: "subMenu12", url: "#" }, { name: "subMenu13", url: "#" }, { name: "subMenu14", url: "#" }] }, { name: "spMenu2", iconClasses: "fa fa-firefox", subMenus: [{ name: "subMenu21", url: "#" }, { name: "subMenu22", url: "#" }, { name: "subMenu23", url: "#" }, { name: "subMenu34", url: "#" }] }, { name: "spMenu3", iconClasses: "fa fa-internet-explorer", subMenus: [{ name: "subMenu31", url: "#" }, { name: "subMenu32", url: "#" }, { name: "subMenu33", url: "#" }, { name: "subMenu34", url: "#" }] }]; var config01 = { menuBoxId: "#menuBox01", multiple: true, openIndex: [] } menuBox.init(config01, dataObj01); var dataObj02 = JSON.stringify(dataObj01); var config02 = { menuBoxId: "#menuBox02", multiple: false, openIndex: [] } menuBox.init(config02, dataObj02); var dataObj03 = { name: "spMenu1", iconClasses: "fa fa-chrome", subMenus: [{ name: "subMenu11", url: "#" }, { name: "subMenu12", url: "#" }, { name: "subMenu13", url: "#" }, { name: "subMenu14", url: "#" }] }; var config03 = { menuBoxId: "#menuBox03", multiple: false, openIndex: [] } menuBox.init(config03, dataObj03); var dataObj04 = JSON.stringify(dataObj03); var config04 = { menuBoxId: "#menuBox04", multiple: true, openIndex: [] } menuBox.init(config04, dataObj04); </script> </html>
menuBox-1.1.css
body { margin: 0; } ul { list-style: none; padding: 0; margin: 0; } /**菜单box**/ .menuBox { width: 300px; margin: 5px; } /**默认不显示二级菜单**/ .menuBox .subMenuBox { display: none; } /**一级菜单样式**/ .spMenuBox>*>.spMenu { align-items: center; background: darkslateblue; border-bottom: 1px solid lightgray; cursor: pointer; color: white; /**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; /**flexbox兼容**/ -webkit-justify-content: space-around; -webkit-box-pack: space-around; -moz-box-pack: space-around; -ms-flex-pack: space-around; justify-content: space-around; /**user-select兼容**/ -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; } /**最后一个一级菜单样式**/ .spMenuBox>*:last-child>.spMenu { align-items: center; background: darkslateblue; border-bottom: 0px; color: white; cursor: pointer; /**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; /**flexbox兼容**/ webkit-justify-content: space-around; -webkit-box-pack: space-around; -moz-box-pack: space-around; -ms-flex-pack: space-around; justify-content: space-around; /**user-select兼容**/ -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; } /**箭头切换用动画实现**/ .spMenuItem>.spMenu>.fa-angle-down { -webkit-transition: all 0.5s ease; -moz-transition: all 0.5s ease; -ms-transition: all 0.5s ease; -o-transition: all 0.5s ease; transition: all 0.5s ease; } .spMenuItem.active>.spMenu>.fa-angle-down { -webkit-transform: rotate(-180deg); -moz-transform: rotate(-180deg); -ms-transform: rotate(-180deg); -o-transform: rotate(-180deg); transform: rotate(-180deg); } /**二级菜单样式*/ .subMenuBox>*>.subMenu { color: darkgray; align-items: center; background: darkgreen; border-bottom: 1px solid lightyellow; cursor: pointer; padding: 5px 10px; /**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; /**user-select兼容**/ -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; } /**最后一个二级菜单样式**/ .subMenuBox>*:last-child>.subMenu { color: darkgray; align-items: center; background: #darkgreen; border-bottom: 0px; cursor: pointer; padding: 5px 10px; /**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; /**user-select兼容**/ -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; }
menuBox-1.1.js:
/** * 需要用到的js: * jquery.js * json2.js * checkutil.js * 示例: * var dataObj01 = [{ * name: "spMenu1", * iconClasses: "fa fa-chrome", * subMenus: [{ * name: "subMenu11", * url: "#" * }, { * name: "subMenu12", * url: "#" * }, { * name: "subMenu13", * url: "#" * }, { * name: "subMenu14", * url: "#" * }] * }, { * name: "spMenu2", * iconClasses: "fa fa-firefox", * subMenus: [{ * name: "subMenu21", * url: "#" * }, { * name: "subMenu22", * url: "#" * }, { * name: "subMenu23", * url: "#" * }, { * name: "subMenu34", * url: "#" * }] * }, { * name: "spMenu3", * iconClasses: "fa fa-internet-explorer", * subMenus: [{ * name: "subMenu31", * url: "#" * }, { * name: "subMenu32", * url: "#" * }, { * name: "subMenu33", * url: "#" * }, { * name: "subMenu34", * url: "#" * }] * }]; * * var config01 = { * menuBoxId: "#menuBox01", * multiple: true, * openIndex: [] * } * menuBox.init(config01, dataObj01); * * var dataObj02 = JSON.stringify(dataObj01); * * var config02 = { * menuBoxId: "#menuBox02", * multiple: false, * openIndex: [] * } * menuBox.init(config02, dataObj02); * * var dataObj03 = { * name: "spMenu1", * iconClasses: "fa fa-chrome", * subMenus: [{ * name: "subMenu11", * url: "#" * }, { * name: "subMenu12", * url: "#" * }, { * name: "subMenu13", * url: "#" * }, { * name: "subMenu14", * url: "#" * }] * }; * var config03 = { * menuBoxId: "#menuBox03", * multiple: false, * openIndex: [] * } * menuBox.init(config03, dataObj03); * * var dataObj04 = JSON.stringify(dataObj03); * var config04 = { * menuBoxId: "#menuBox04", * multiple: true, * openIndex: [] * } * menuBox.init(config04, dataObj04); * * @author DarkRanger * http: //www.cnblogs.com/wrcold520/ */ ! function($, JSON, checkutil) { "use strict"; var menuBox = function() {}; //要配置的menuBox的菜单id menuBox.menuBoxId = undefined; //是否可以显示多个上级菜单的子菜单 menuBox.multiple = false; //默认关闭所有一级菜单 menuBox.openIndex = []; //menuBox初始化方法 menuBox.init = function(config, data) { var cntMenuBox = new menuBox(); var menuBoxEle; //定义上级菜单spMenu数组 var spMenus; var boxId = config.menuBoxId; var menuBoxEle = $(boxId); if(boxId == undefined) { console.warn("Your menuBox config has not key['menuBoxId'], configure failed!!! Please configure your unique menuBox by MenuBoxId!"); return; } else if(menuBoxEle.length == 0) { console.warn("Cannot find your menuBox[id: " + boxId + "], configure failed!!! "); return; } else { cntMenuBox.menuBoxId = $(config.menuBoxId) ? config.menuBoxId : undefined; menuBoxEle = $(cntMenuBox.menuBoxId); if(data) { genDomByData(menuBoxEle, data); } } if(config.multiple == undefined) { 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!"); } else { cntMenuBox.multiple = config.multiple; } if(config.openIndex == undefined) { console.warn("your config has not key['openIndex'] , default value is a Number Array which's length is 0!"); } else if(!config.openIndex instanceof Array) { throw new Error("your config 'openIndex' should be a number Array"); } else { cntMenuBox.openIndex = unique(config.openIndex, false); } //确定对应的menuBox cntMenuBox.menuBoxId = config.menuBoxId; //是否打开其他某一个的时候关闭其他选项 var closeOthers = !cntMenuBox.multiple; //初始化点击事件 initClickEvent(cntMenuBox, closeOthers); //确定上级菜单数组 spMenus = $(cntMenuBox.menuBoxId + " .spMenu"); //打开传入的数组 for(var i in cntMenuBox.openIndex) { var index = cntMenuBox.openIndex[i]; var spMenu = spMenus[index]; if(spMenu) { openSpMenu(cntMenuBox.menuBoxId, index); if(!cntMenuBox.multiple) { break; } } } }; /** * 循环创建dom树 * @param {Object} menuBoxEle menuBoxEle的根元素(Jquery对象元素) * @param {Object} data */ function genDomByData(menuBoxEle, data) { var dataObj; //JS Object or JS Array if(checkutil.isArray(data)) { dataObj = data; } else if(checkutil.isObject(data)) { dataObj = [data]; } //JSONString else if(checkutil.isString(data)) { var menuObj; try { var menuJson = JSON.parse(data); if(checkutil.isArray(menuJson)) { menuObj = menuJson; } else if(checkutil.isObject(menuJson)) { menuObj = [menuJson]; } dataObj = menuObj; } catch(e) { throw new Error("Please modify your data to a standard jsonString or Array!!! 请修改您传入的data为标准的json字符串或者数组!!!"); } } //创建ul var spMenuBoxEle = $("<ul>", { "class": "spMenuBox", }); //循环创建li $.each(dataObj, function(index, spMenuItem) { var spMenuItemEle = $("<li>", { "class": "spMenuItem" }); //创建li下面的div var spMenuDiv = $("<div>", { "class": "spMenu", }); //创建div下面文本前面的icon var iconBefore = $("<i>", { "class": spMenuItem.iconClasses, }); //创建文本 var menuSpan = $("<span>", { text: spMenuItem.name, }); //创建div下面文本后面的icon var iconAfter = $("<i>", { "class": "fa fa-2x fa-angle-down" }); iconBefore.appendTo(spMenuDiv); menuSpan.appendTo(spMenuDiv); iconAfter.appendTo(spMenuDiv); spMenuDiv.appendTo(spMenuItemEle); //创建子menu的ul var subMenuBox = $("<ul>", { "class": "subMenuBox", }) $.each(spMenuItem.subMenus, function(index, subMenu) { //<li><span class="subMenu">菜单1.1</span></li> var subMenuItem = $("<li>", {}) var subMenuSpan = $("<a>", { "class": "subMenu", "href": subMenu.url, text: subMenu.name }) subMenuSpan.appendTo(subMenuItem); subMenuItem.appendTo(subMenuBox); }); subMenuBox.appendTo(spMenuItemEle); spMenuItemEle.appendTo(spMenuBoxEle); }); spMenuBoxEle.appendTo(menuBoxEle); } function unique(arr) { var result = [], hash = {}; for(var i = 0, elem; (elem = arr[i]) != null; i++) { if(!hash[elem]) { result.push(elem); hash[elem] = true; } } return result; } //初始化点击事件 function initClickEvent(menuBox, closeOthers) { $(menuBox.menuBoxId + " .spMenu").on("click", function() { var cntSpMenu$ = $(this); //要切换的元素 cntSpMenu$.next().slideToggle(); cntSpMenu$.parent().toggleClass("active") var cntSpMenu = cntSpMenu$['context']; if(closeOthers == true) { var spMenus = $(menuBox.menuBoxId + " .spMenu"); $.each(spMenus, function(index, spMenu) { if(cntSpMenu != spMenu) { closeSpMenu(menuBox.menuBoxId, index); } }); } }); } //打开某一个item function openSpMenu(menuBoxId, index) { //要切换的元素 var spItem = $(menuBoxId + " .spMenu:eq(" + index + ")"); spItem.next().slideDown(); spItem.parent().addClass("active") } //关闭某一个item function closeSpMenu(menuBoxId, index) { //要切换的元素 var spItem = $(menuBoxId + " .spMenu:eq(" + index + ")"); spItem.next().slideUp(); spItem.parent().removeClass("active") } //切换某一个item function toggleSpMenu(menuBoxId, index) { //要切换的元素 var spItem = $(menuBoxId + " .spMenu:eq(" + index + ")"); spItem.next().slideToggle(); spItem.parent().toggleClass("active") } window.menuBox = menuBox; }($, JSON, checkutil);
源码下载地址:menuBox1.1.zip