目前网上有很多各种各样的手风琴插件,但是没有一个完整实现了的侧菜单,今天写了一个可以无限子节点的手风琴侧菜单,有需要的可以参考一下,有什么好的想法可以留言。(没有经过彻底测试,不过问题应该不大)
下面老规矩,直接贴代码:
1 (function ($) { 2 'use strict'; 3 var defaults = { 4 url: null, 5 param: {}, 6 data: {}, 7 fill: true, 8 level_space: 15, 9 onitemclick: null, 10 style: { 11 header: "accordion-header", 12 header_title: "accordion-header-title", 13 content: "accordion-content", 14 selected: "selected", 15 icon_base: "fa", 16 icon_collapse: "fa-angle-up", 17 icon_expand: "fa-angle-down" 18 } 19 } 20 var methods = { 21 init: function (options) { 22 return this.each(function () { 23 var $this = $(this); 24 if (!$this.hasClass("accordion")) { 25 $this.addClass("accordion"); 26 } 27 var settings = $this.data('tw.accordion'); 28 if (typeof (settings) == 'undefined') { 29 settings = $.extend({}, defaults, options); 30 $this.data('tw.accordion', settings); 31 } else { 32 settings = $.extend({}, settings, options); 33 $this.data('tw.accordion', settings); 34 } 35 if (settings.url) { 36 $.ajax({ 37 type: "post", 38 async: false, 39 url: settings.url, 40 data: settings.param, 41 success: function (data) { 42 settings.data = data; 43 } 44 }); 45 } 46 if (settings.fill) { 47 $this.height("100%"); 48 } 49 if (settings.data.length > 0) { 50 $this.data("count", settings.data.length); 51 $.each(settings.data, function () { 52 this.level = 1; 53 var item = $this.accordion("add", this); 54 $this.append(item); 55 }); 56 if ($this.find("." + settings.style.selected).length == 0) { 57 var data = $this.find(">li:first-child").data("data"); 58 $this.accordion("select", data); 59 } 60 } 61 }); 62 }, 63 add: function (data) { 64 var $this = $(this); 65 var settings = $this.data("tw.accordion"); 66 var item = $("<li class='" + settings.style.header + "'></li>"); 67 item.data("data", data); 68 var header = $("<div class='" + settings.style.header_title + "' data-accordion='" + data.id + "'>" + 69 "<i class='" + settings.style.icon_base + "" + data.icon + "'></i>" + 70 "<span>" + data.name + "</span></div>"); 71 header.css("padding-left", settings.level_space * data.level); 72 item.append(header); 73 if (data.childrens) { 74 var toggle = $("<i class='" + settings.style.icon_base + "" + settings.style.icon_collapse + "'></i>"); 75 toggle.css({ "font-size": "1.4em", "position": "absolute", "top": "7px", "right": "7px" }); 76 header.append(toggle); 77 var content = $("<ul class='" + settings.style.content + "'></ul>"); 78 content.data("count", data.childrens.length); 79 $.each(data.childrens, function () { 80 this.level = data.level + 1; 81 var child = $this.accordion("add", this); 82 content.append(child); 83 }); 84 item.append(content); 85 } 86 header.click(function () { 87 $this.accordion("select", data); 88 }); 89 if (data.selected) { 90 $this.accordion("select", data); 91 } 92 return item; 93 }, 94 select: function (data) { 95 var $this = $(this); 96 var settings = $this.data("tw.accordion"); 97 var header = $this.find("[data-accordion='" + data.id + "']"); 98 var item = header.parent(); 99 if (!header.hasClass(settings.style.selected) && !item.hasClass(settings.style.selected)) { 100 var sibling = item.siblings(); 101 sibling.removeClass(settings.style.selected).children("." + settings.style.selected).removeClass(settings.style.selected); 102 sibling.children("." + settings.style.icon_expand).removeClass(settings.style.icon_expand).addClass(settings.style.icon_collapse); 103 if (data.childrens) { 104 item.addClass(settings.style.selected); 105 header.find("." + settings.style.icon_collapse).removeClass(settings.style.icon_collapse).addClass(settings.style.icon_expand); 106 if (settings.fill) { 107 var count = item.parent().data("count") - 1; 108 item.css("height", "calc(100% - " + (item.height() * count) + "px)"); 109 } 110 } else { 111 header.addClass(settings.style.selected); 112 } 113 } 114 if (settings.onitemclick) { 115 settings.onitemclick(data); 116 } 117 }, 118 update: function (url, param) { 119 var $this = $(this); 120 var settings = $this.data("tw.accordion"); 121 if (typeof url == "object") { 122 settings.param = url; 123 } else { 124 settings.url = url; 125 settings.param = param; 126 } 127 $this.accordion("init", settings); 128 }, 129 destroy: function (options) { 130 return $(this).each(function () { 131 var $this = $(this); 132 $this.removeData('accordion'); 133 }); 134 } 135 } 136 $.fn.accordion = function () { 137 var method = arguments[0]; 138 var args = arguments; 139 if (typeof (method) == 'object' || !method) { 140 method = methods.init; 141 } else if (methods[method]) { 142 method = methods[method]; 143 args = $.makeArray(arguments).slice(1); 144 } else { 145 $.error('Method ' + method + ' does not exist on tw.accordion'); 146 return this; 147 } 148 return method.apply(this, args); 149 } 150 })(jQuery);
1 .accordion { 2 margin:0; 3 padding:0; 4 font-size:14px; 5 } 6 .accordion > .accordion-header { 7 list-style: none; 8 margin: 0; 9 padding: 0; 10 border-bottom: 1px solid #ddd; 11 } 12 .accordion > .accordion-header.selected > .accordion-header-title { 13 color: #0094ff; 14 } 15 .accordion > .accordion-header > .accordion-header-title { 16 position: relative; 17 100%; 18 height: 35px; 19 line-height: 35px; 20 background: #eee; 21 border-bottom: 1px solid #ccc; 22 cursor: pointer; 23 } 24 .accordion > .accordion-header > .accordion-header-title > i:first-child { 25 font-size: 1.3em; 26 } 27 .accordion > .accordion-header > .accordion-header-title > span { 28 position: relative; 29 top: -1px; 30 left: 5px; 31 } 32 .accordion > .accordion-header > .accordion-content { 33 display: none; 34 100%; 35 height: calc(100% - 35px); 36 margin: 0; 37 padding: 0; 38 } 39 .accordion > .accordion-header.selected > .accordion-content { 40 display: block; 41 } 42 .accordion-content > .accordion-header { 43 list-style: none; 44 margin: 0; 45 padding: 0; 46 } 47 .accordion-content > .accordion-header.selected { 48 color: #0094ff; 49 } 50 .accordion-content > .accordion-header > .accordion-header-title { 51 position: relative; 52 100%; 53 height: 32px; 54 line-height: 32px; 55 cursor: pointer; 56 border-bottom: 1px solid #ccc; 57 } 58 .accordion-content > .accordion-header > .accordion-header-title:hover { 59 background:#eee; 60 } 61 .accordion-content > .accordion-header > .accordion-header-title.selected { 62 color: #fff; 63 background: #0094ff; 64 border-left: 3px solid #ff6a00; 65 border-bottom: 0px; 66 } 67 .accordion-content > .accordion-header > .accordion-header-title > i:first-child { 68 font-size: 1.2em; 69 } 70 .accordion-content > .accordion-header > .accordion-header-title > span { 71 position: relative; 72 top: -1px; 73 left: 5px; 74 } 75 .accordion-content > .accordion-header > .accordion-header-title.selected > i:first-child { 76 position:relative; 77 left:-3px; 78 } 79 .accordion-content > .accordion-header > .accordion-header-title.selected > span { 80 position: relative; 81 top: -1px; 82 left: 2px; 83 } 84 .accordion-content > .accordion-header > .accordion-content { 85 display: none; 86 100%; 87 height: calc(100% - 32px); 88 margin: 0; 89 padding: 0; 90 } 91 .accordion-content > .accordion-header.selected > .accordion-content { 92 display: block; 93 }