html自定義垂直導航菜單(目前只支持上級+下級兩級菜單)
由於工作的需要,昨天花了三個多小時的事件整理了一份關於垂直導航二級菜單,可以通過js配置的方式初始化菜單box(測試環境:chrome 49、IE 10、IE edge)。
no pic u say a j8? 好吧,先上效果圖(由於下面是gif,所以一幀一幀的感覺不流暢。講道理,事實上,切換非常流暢,自行下載看Demo)。
js配置方式:
配置menuBox的方式:menuBox.init(config);
這里的config有三個屬性:
menuBoxId(必需,你要配置的菜單根節點所在元素的Id)
multiple(可選,是否可以同時打開多個上級菜單,默認是false,也就是最多顯示一個上級菜單的子菜單)
openIndex(可選,初始化要打開上級菜單的index數組,如果你要傳值,按照格式應該是數字數組)
//配置第一個手風琴的基本參數
var config01 = {
//配置菜單的MenuBoxId
menuBoxId: "#menuBox01", //是否可以打開多個上級菜單的子菜單 multiple: false, //初始化打開的 openIndex: [3, 4, 5] } menuBox.init(config01);
然后看下兩個菜單Box的配置:
第一個菜單Box:可以同時打開多個上級菜單,初始化的時候打開第0、1個。
//配置第一個手風琴的基本參數 var config01 = { //配置菜單的MenuBoxId menuBoxId: "#menuBox01", //是否可以打開多個二級菜單 multiple: true, //初始化打開的 openIndex: [0,1] } menuBox.init(config01);
第二個菜單Box:不可以打開多個上級菜單,初始化的時候打開第1個,如果傳入數組有多個值,默認打開第一個有效的index上級菜單。 //配置第二個手風琴的基本參數 var config02 = { //配置菜單的MenuBoxId menuBoxId: "#menuBox02", //是否可以打開多個二級菜單 multiple: false, //初始化打開的 openIndex: [-1, 1] } menuBox.init(config02);
用到的知識點:
1、flexbox(在ie9及以下布局不兼容,但是還是可以正常看到切換效果)。
2、css3 transform配合transition實現箭頭的旋轉切換。
3、打開菜單:$().slideDown()、關閉菜單:$().slideUp()、切換菜單:$().slideToggle()。有時間我會修改為css3動畫實現切換,盡量不用jquery。
4、<i>標簽引用圖標font-awesome
下面是相關代碼:
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.css" /> <script type="text/javascript" src="js/jquery-2.2.2.min.js"></script> <script type="text/javascript" src="js/menuBox.js"></script> <title>MenuBox</title> </head> <style> .top { background: lightblue; min-height: 55px; } </style> <body> <div id="top" class="top"> <span> var config01 = {<br> menuBoxId: "#menuBox01",<br> multiple: true,<br> openIndex: [0,1]<br> }<br> menuBox.init(config01);<br><br> var config02 = {<br> menuBoxId: "#menuBox02",<br> multiple: false,<br> openIndex: [-1, 1]<br> }<br> menuBox.init(config02);<br> </span> </div> <div id="leftNav" class="left-nav"> <!-- 作者:15934179313@163.com 時間:2016-08-03 描述:第一個手風琴二級菜單 --> <div id="menuBox01" class="menuBox"> <ul class="spMenuBox"> <li class="spMenuItem"> <div class="spMenu"> <i class="fa fa-chrome"></i> <span>菜單1</span> <i class="fa fa-2x fa-angle-down"></i> </div> <ul class="subMenuBox"> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> </ul> </li> <li class="spMenuItem"> <div class="spMenu"> <i class="fa fa-chrome"></i> <span>菜單1</span> <i class="fa fa-2x fa-angle-down"></i> </div> <ul class="subMenuBox"> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> </ul> </li> <li class="spMenuItem"> <div class="spMenu"> <i class="fa fa-chrome"></i> <span>菜單1</span> <i class="fa fa-2x fa-angle-down"></i> </div> <ul class="subMenuBox"> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> </ul> </li> <li class="spMenuItem"> <div class="spMenu"> <i class="fa fa-chrome"></i> <span>菜單1</span> <i class="fa fa-2x fa-angle-down"></i> </div> <ul class="subMenuBox"> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> </ul> </li> <li class="spMenuItem"> <div class="spMenu"> <i class="fa fa-chrome"></i> <span>菜單1</span> <i class="fa fa-2x fa-angle-down"></i> </div> <ul class="subMenuBox"> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> </ul> </li> <li class="spMenuItem"> <div class="spMenu"> <i class="fa fa-chrome"></i> <span>菜單1</span> <i class="fa fa-2x fa-angle-down"></i> </div> <ul class="subMenuBox"> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> </ul> </li> <li class="spMenuItem"> <div class="spMenu"> <i class="fa fa-chrome"></i> <span>菜單1</span> <i class="fa fa-2x fa-angle-down"></i> </div> <ul class="subMenuBox"> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> </ul> </li> <li class="spMenuItem"> <div class="spMenu"> <i class="fa fa-chrome"></i> <span>菜單1</span> <i class="fa fa-2x fa-angle-down"></i> </div> <ul class="subMenuBox"> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> </ul> </li> <li class="spMenuItem"> <div class="spMenu"> <i class="fa fa-chrome"></i> <span>菜單1</span> <i class="fa fa-2x fa-angle-down"></i> </div> <ul class="subMenuBox"> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> </ul> </li> <li class="spMenuItem"> <div class="spMenu"> <i class="fa fa-chrome"></i> <span>菜單1</span> <i class="fa fa-2x fa-angle-down"></i> </div> <ul class="subMenuBox"> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> </ul> </li> <li class="spMenuItem"> <div class="spMenu"> <i class="fa fa-chrome"></i> <span>菜單1</span> <i class="fa fa-2x fa-angle-down"></i> </div> <ul class="subMenuBox"> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> </ul> </li> <li class="spMenuItem"> <div class="spMenu"> <i class="fa fa-chrome"></i> <span>菜單1</span> <i class="fa fa-2x fa-angle-down"></i> </div> <ul class="subMenuBox"> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> <li><span class="subMenu">菜單1.1</span></li> <li><span class="subMenu">菜單1.2</span></li> <li><span class="subMenu">菜單1.3</span></li> </ul> </li> </ul> </div> <!-- 作者:15934179313@163.com 時間:2016-08-03 描述:第二個手風琴菜單 --> <div id="menuBox02" class="menuBox"> <div class="spMenuBox"> <div class="spMenuItem"> <div class="spMenu"> <i class="fa fa-chrome"></i> <span>菜單1</span> <i class="fa fa-2x fa-angle-down"></i> </div> <div class="subMenuBox"> <div><span class="subMenu">菜單1.1</span></div> <div><span class="subMenu">菜單1.2</span></div> <div><span class="subMenu">菜單1.3</span></div> </div> </div> <div class="spMenuItem"> <div class="spMenu"> <i class="fa fa-chrome"></i> <span>菜單1</span> <i class="fa fa-2x fa-angle-down"></i> </div> <div class="subMenuBox"> <div><span class="subMenu">菜單1.1</span></div> <div><span class="subMenu">菜單1.2</span></div> <div><span class="subMenu">菜單1.3</span></div> </div> </div> <div class="spMenuItem"> <div class="spMenu"> <i class="fa fa-chrome"></i> <span>菜單1</span> <i class="fa fa-2x fa-angle-down"></i> </div> <div class="subMenuBox"> <div><span class="subMenu">菜單1.1</span></div> <div><span class="subMenu">菜單1.2</span></div> <div><span class="subMenu">菜單1.3</span></div> </div> </div> </div> </div> </div> </body> <script> $().ready(function() { initLeftNavHeight(); initMenu(); }) /**初始化左側導航欄高度**/ function initLeftNavHeight() { initHeight(); function initHeight() { var total = document.documentElement.clientHeight; var topHeight = $("#top").height(); $("#leftNav").height(total - topHeight); } document.body.onresize = function() { initHeight(); } } /**初始化菜單選項**/ function initMenu() { //配置第一個手風琴的基本參數 var config01 = { //配置菜單的MenuBoxId menuBoxId: "#menuBox01", //是否可以打開多個上級菜單 multiple: true, //初始化打開的 openIndex: [0,2] } menuBox.init(config01); //配置第二個手風琴的基本參數 var config02 = { //配置菜單的MenuBoxId menuBoxId: "#menuBox02", //是否可以打開多個上級菜單 multiple: false, //初始化打開的上級菜單的index數組 openIndex: [-1, 1] } menuBox.init(config02); } </script> </html>
menuBox.css:
body { margin: 0; } ul { list-style: none; padding: 0; margin: 0; } .left-nav { background: lightgray; height: 100%; overflow-y: overlay; position: absolute; /**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; } /**菜單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; } /**箭頭切換用動畫實現**/ .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 { align-items: center; background: #ccc; 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 { align-items: center; background: #ccc; 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.js:
/** * 配置菜單 * 示例: * 配置基本參數 * var config = { * //配置菜單的MenuBoxId * menuBoxId: "#menuBox01", * //是否可以打開多個上級菜單 * multiple: true, * //初始化打開的菜單數組 * openIndex: [1, 3, 5] * } * menuBox.init(config); * * @author DarkRanger * http: //www.cnblogs.com/wrcold520/ */ ! function($) { if($ == undefined) { throw new Error("please put your jquery.js top of menuBox.js!") } var menuBox = function() {}; //要配置的menuBox的菜單id menuBox.menuBoxId = undefined; //是否可以顯示多個上級菜單的子菜單 menuBox.multiple = false; //默認關閉所有一級菜單 menuBox.openIndex = []; //menuBox初始化方法 menuBox.init = function(config) { var cntMenuBox = new menuBox(); //定義上級菜單spMenu數組 var spMenus; if(config.menuBoxId == undefined) { throw new Error("your config has not 'menuBoxId', please make sure your menuBox is existed!"); } else { cntMenuBox.menuBoxId = $(config.menuBoxId) ? config.menuBoxId : undefined; } if(config.multiple == undefined) { console.warn("your config has not 'multiple', default value is false which means you can open only one spMenu at the same time!"); } else { cntMenuBox.multiple = config.multiple; } if(config.openIndex == undefined) { console.warn("your config has not 'openIndex', default value is a 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; } } } } 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; }($);
附上源碼: