—————————————————————————————————————————————————————————
使用方法
實現效果
引入文件
<link rel="stylesheet" href="vendor/bootstrap/css/bootstrap.css"> // bootstrap樣式
<link href="vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css"> // 圖標使用font-awesome
<link rel="stylesheet" href="vendor/metisMenu/metisMenu.css"> // 插件樣式
<script src="vendor/jquery/jquery.js"></script> // 基於jquery實現
<script src="vendor/bootstrap/js/bootstrap.min.js"></script> // 使用bootstrap的collapse插件
<script src="vendor/metisMenu/metisMenu.min.js"></script> // 插件代碼
調用方法
<script type="text/javascript"> $(function() { $('#side-menu').metisMenu(); // ul.nav#side-menu }) </script>
使用樣例
<<Demo.html>>
<nav class="navbar navbar-default navbar-static-top"> <div class="navbar-default sidebar" role="navigation"> <div class="sidebar-nav navbar-collapse"> <ul class="nav" id="side-menu"> <li class="sidebar-search"> <div class="input-group custom-search-form"> <input type="text" class="form-control" placeholder="Search..."> <span class="input-group-btn"> <button class="btn btn-default" type="button"> <i class="fa fa-search"></i> </button> </span> </div> </li> <li> <a href=""><i class="fa fa-dashboard fa-fw"></i> Dashboard</a> </li> <li> <a href="#"><i class="fa fa-bar-chart-o fa-fw"></i> Charts<span class="fa arrow"></span></a> <ul class="nav nav-second-level"> <li> <a href="">Flot Charts</a> </li> <li> <a href="">Morris.js Charts</a> </li> </ul> </li> <li> <a href=""><i class="fa fa-table fa-fw"></i> Tables</a> </li> <li> <a href=""><i class="fa fa-edit fa-fw"></i> Forms</a> </li> <li> <a href="#"><i class="fa fa-wrench fa-fw"></i> UI Elements<span class="fa arrow"></span></a> <ul class="nav nav-second-level"> <li> <a href="">Panels and Wells</a> </li> <li> <a href="">Buttons</a> </li> <li> <a href="">Notifications</a> </li> <li> <a href="">Typography</a> </li> <li> <a href=""> Icons</a> </li> <li> <a href="">Grid</a> </li> </ul> </li> <li> <a href="#"><i class="fa fa-sitemap fa-fw"></i> Multi-Level Dropdown<span class="fa arrow"></span></a> <ul class="nav nav-second-level"> <li> <a href="#">Second Level Item</a> </li> <li> <a href="#">Second Level Item</a> </li> <li> <a href="#">Third Level <span class="fa arrow"></span></a> <ul class="nav nav-third-level"> <li> <a href="#">Third Level Item</a> </li> <li> <a href="#">Third Level Item</a> </li> <li> <a href="#">Third Level Item</a> </li> <li> <a href="#">Third Level Item</a> </li> </ul> </li> </ul> </li> <li class="active"> <a href="#"><i class="fa fa-files-o fa-fw"></i> Sample Pages<span class="fa arrow"></span></a> <ul class="nav nav-second-level"> <li> <a class="active" href="#">Blank Page</a> </li> <li> <a href="#">Login Page</a> </li> </ul> </li> </ul> </div> </div> </nav>
<<blank.css>>
@media (min-width: 768px) { .sidebar {position: absolute;width: 250px;margin-top: 51px;z-index: 2;} } .sidebar .sidebar-search {padding: 15px;} .sidebar ul li a.active {background-color: #eee;} .sidebar ul li {background: #f8f8f8;border-bottom: #e7e7e7 1px solid;} .nav-second-level li {border-bottom: 0 !important;} .nav-second-level li a {padding-left: 38px;}
樹形圖
p.s.自定義樣式用下划線表示
—————————————————————————————————————————————————————————
源碼解讀
調用
使用$.fn.extend(object)的方式為jquery類添加成員方法,功能封裝在原型中,能夠全局調用;
通過$("#side-menu")生成的jquery類實例來調用該方法;
初始配置
全局定義插件名稱pluginName,定義對象defaults存放toggle(展開/閉合)與doubleTapToGo(雙擊事件)的開關;
樣式
使用font-awesome來擴展側邊欄圖標和展開標識(三角),引入font-awesome.css后只需要通過i.fa.fa-***來調用就可以了
基礎布局通過bootstrap類實現,詳細分支情況見屬性圖
初始化展開
借助bootstrap內置的collapse插件來實現;
通過檢測<li.active>來標識當前頁對應的列表,在metisMenu.js中檢查是否需要展開的列表;
判斷激活的標簽欄是否有子列表,如果有則添加.collapse.in類(bootstrap.css),實際為添加樣式{display:block};
未被激活的標簽欄如果有子列表則添加.collapse類(boostrap.css),{display:none};
監聽點擊事件
監聽方法借助bootstrap的collapse插件;
綁定事件時需要遵循collapse插件規則.on("click"+"."+pluginName,function(e){});
為點擊的標簽欄添加激活樣式.active,如果有子列表則展開/關閉,使用collapse插件方法.collapse("toggle");
閉合其他所有有子列表的標簽欄,使用.collapse("hide");
—————————————————————————————————————————————————————————
簡單版 v1.0
功能
僅實現基礎效果
復寫代碼
<<metisMenu-demo1.js>>
/** * Created by hughd on 2017/8/9. * 簡單版 - v1.0 * 僅實現基礎折疊 */ ;(function ($, window, document, undefined) { var pluginName = "metisMenu"; var toggle = true; function Plugin(element, options) { this.element = $(element); this.init(); } Plugin.prototype = { init: function () { var $this = this.element; // var obj = this; $this.find("li.active").has("ul").children("ul").addClass('collapse in');// 初始激活的元素的后代全部展開 $this.find('li').not(".active").has("ul").children("ul").addClass('collapse');// 未激活的元素顯示隱藏 // 監聽點擊事件 $this.find("li").children("a").on("click." + pluginName, function () { //被點擊的元素激活樣式並展開 $(this).parent('li').toggleClass('active').children("ul").collapse("toggle"); if (toggle) { //將其他被展開的元素閉合 $(this).parent("li").siblings().removeClass("active").children("ul").collapse("hide"); } }); } } $.fn[pluginName] = function (options) { // 實例化Plugin對象,並存放在元素<ul#side-menu>._proto_.metisMenu中 this.data(pluginName, new Plugin(this, options)); return this; } })(jQuery, window, document);
實現思路
-
初始化
獲取當前激活的標簽,將該標簽的內容顯示(如果沒有子標簽則不顯示)
未激活的標簽,所有子列表隱藏
-
點擊事件 ( 通過 boostrap 的 collapse 插件 )
當前點擊的標簽獲取激活樣式,子列表展開
除點擊標簽之外的其他標簽移除激活樣式,並閉合
—————————————————————————————————————————————————————————
完整插件
功能
IE瀏覽器兼容情況;
移除已有metisMenu數據情況
雙擊標題事件
源碼
<<metisMenu.js>>
/* * metismenu - v1.1.3 * Easy menu jQuery plugin for Twitter Bootstrap 3 * https://github.com/onokumus/metisMenu * * Made by Osman Nuri Okumus * Under MIT License */ ;(function($, window, document, undefined) { var pluginName = "metisMenu", defaults = { toggle: true, doubleTapToGo: false }; function Plugin(element, options) { this.element = $(element); this.settings = $.extend({}, defaults, options); this._defaults = defaults; this._name = pluginName; this.init(); } Plugin.prototype = { init: function() { var $this = this.element, $toggle = this.settings.toggle, obj = this; if (this.isIE() <= 9) { $this.find("li.active").has("ul").children("ul").collapse("show"); $this.find("li").not(".active").has("ul").children("ul").collapse("hide"); } else { $this.find("li.active").has("ul").children("ul").addClass("collapse in"); $this.find("li").not(".active").has("ul").children("ul").addClass("collapse"); } //add the "doubleTapToGo" class to active items if needed if (obj.settings.doubleTapToGo) { $this.find("li.active").has("ul").children("a").addClass("doubleTapToGo"); } $this.find("li").has("ul").children("a").on("click" + "." + pluginName, function(e) { e.preventDefault(); //Do we need to enable the double tap if (obj.settings.doubleTapToGo) { //if we hit a second time on the link and the href is valid, navigate to that url if (obj.doubleTapToGo($(this)) && $(this).attr("href") !== "#" && $(this).attr("href") !== "") { e.stopPropagation(); document.location = $(this).attr("href"); return; } } $(this).parent("li").toggleClass("active").children("ul").collapse("toggle"); if ($toggle) { $(this).parent("li").siblings().removeClass("active").children("ul.in").collapse("hide"); } }); }, isIE: function() { //https://gist.github.com/padolsey/527683 var undef, v = 3, div = document.createElement("div"), all = div.getElementsByTagName("i"); while ( div.innerHTML = "<!--[if gt IE " + (++v) + "]><i></i><![endif]-->", all[0] ) { return v > 4 ? v : undef; } }, //Enable the link on the second click. doubleTapToGo: function(elem) { var $this = this.element; //if the class "doubleTapToGo" exists, remove it and return if (elem.hasClass("doubleTapToGo")) { elem.removeClass("doubleTapToGo"); return true; } //does not exists, add a new class and return false if (elem.parent().children("ul").length) { //first remove all other class $this.find(".doubleTapToGo").removeClass("doubleTapToGo"); //add the class on the current element elem.addClass("doubleTapToGo"); return false; } }, remove: function() { this.element.off("." + pluginName); this.element.removeData(pluginName); } }; $.fn[pluginName] = function(options) { this.each(function () { var el = $(this); if (el.data(pluginName)) { el.data(pluginName).remove(); } el.data(pluginName, new Plugin(this, options)); }); return this; }; })(jQuery, window, document);
<<metisMenu.css>>
/* * metismenu - v1.1.3 * Easy menu jQuery plugin for Twitter Bootstrap 3 * https://github.com/onokumus/metisMenu * * Made by Osman Nuri Okumus * Under MIT License */ .arrow { float: right; line-height: 1.42857; } .glyphicon.arrow:before { content: "\e079"; } .active > a > .glyphicon.arrow:before { content: "\e114"; } /* * Require Font-Awesome * http://fortawesome.github.io/Font-Awesome/ */ .fa.arrow:before { content: "\f104"; } .active > a > .fa.arrow:before { content: "\f107"; } .plus-times { float: right; } .fa.plus-times:before { content: "\f067"; } .active > a > .fa.plus-times { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); } .plus-minus { float: right; } .fa.plus-minus:before { content: "\f067"; } .active > a > .fa.plus-minus:before { content: "\f068"; }