在上一篇中我简单写了个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:;
} ul {
list-style: none;
padding:;
margin:;
} /**菜单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!!!\nPlease 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!!!\n请修改您传入的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