目前网上有很多各种各样的手风琴插件,但是没有一个完整实现了的侧菜单,今天写了一个可以无限子节点的手风琴侧菜单,有需要的可以参考一下,有什么好的想法可以留言。(没有经过彻底测试,不过问题应该不大)
下面老规矩,直接贴代码:
(function ($) {
'use strict';
var defaults = {
url: null,
param: {},
data: {},
fill: true,
level_space: 15,
onitemclick: null,
style: {
header: "accordion-header",
header_title: "accordion-header-title",
content: "accordion-content",
selected: "selected",
icon_base: "fa",
icon_collapse: "fa-angle-up",
icon_expand: "fa-angle-down"
}
}
var methods = {
init: function (options) {
return this.each(function () {
var $this = $(this);
if (!$this.hasclass("accordion")) {
$this.addclass("accordion");
}
var settings = $this.data('tw.accordion');
if (typeof (settings) == 'undefined') {
settings = $.extend({}, defaults, options);
$this.data('tw.accordion', settings);
} else {
settings = $.extend({}, settings, options);
$this.data('tw.accordion', settings);
}
if (settings.url) {
$.ajax({
type: "post",
async: false,
url: settings.url,
data: settings.param,
success: function (data) {
settings.data = data;
}
});
}
if (settings.fill) {
$this.height("100%");
}
if (settings.data.length > 0) {
$this.data("count", settings.data.length);
$.each(settings.data, function () {
this.level = 1;
var item = $this.accordion("add", this);
$this.append(item);
});
if ($this.find("." + settings.style.selected).length == 0) {
var data = $this.find(">li:first-child").data("data");
$this.accordion("select", data);
}
}
});
},
add: function (data) {
var $this = $(this);
var settings = $this.data("tw.accordion");
var item = $("<li class='" + settings.style.header + "'></li>");
item.data("data", data);
var header = $("<div class='" + settings.style.header_title + "' data-accordion='" + data.id + "'>" +
"<i class='" + settings.style.icon_base + "" + data.icon + "'></i>" +
"<span>" + data.name + "</span></div>");
header.css("padding-left", settings.level_space * data.level);
item.append(header);
if (data.childrens) {
var toggle = $("<i class='" + settings.style.icon_base + "" + settings.style.icon_collapse + "'></i>");
toggle.css({ "font-size": "1.4em", "position": "absolute", "top": "7px", "right": "7px" });
header.append(toggle);
var content = $("<ul class='" + settings.style.content + "'></ul>");
content.data("count", data.childrens.length);
$.each(data.childrens, function () {
this.level = data.level + 1;
var child = $this.accordion("add", this);
content.append(child);
});
item.append(content);
}
header.click(function () {
$this.accordion("select", data);
});
if (data.selected) {
$this.accordion("select", data);
}
return item;
},
select: function (data) {
var $this = $(this);
var settings = $this.data("tw.accordion");
var header = $this.find("[data-accordion='" + data.id + "']");
var item = header.parent();
if (!header.hasclass(settings.style.selected) && !item.hasclass(settings.style.selected)) {
var sibling = item.siblings();
sibling.removeclass(settings.style.selected).children("." + settings.style.selected).removeclass(settings.style.selected);
sibling.children("." + settings.style.icon_expand).removeclass(settings.style.icon_expand).addclass(settings.style.icon_collapse);
if (data.childrens) {
item.addclass(settings.style.selected);
header.find("." + settings.style.icon_collapse).removeclass(settings.style.icon_collapse).addclass(settings.style.icon_expand);
if (settings.fill) {
var count = item.parent().data("count") - 1;
item.css("height", "calc(100% - " + (item.height() * count) + "px)");
}
} else {
header.addclass(settings.style.selected);
}
}
if (settings.onitemclick) {
settings.onitemclick(data);
}
},
update: function (url, param) {
var $this = $(this);
var settings = $this.data("tw.accordion");
if (typeof url == "object") {
settings.param = url;
} else {
settings.url = url;
settings.param = param;
}
$this.accordion("init", settings);
},
destroy: function (options) {
return $(this).each(function () {
var $this = $(this);
$this.removedata('accordion');
});
}
}
$.fn.accordion = function () {
var method = arguments[0];
var args = arguments;
if (typeof (method) == 'object' || !method) {
method = methods.init;
} else if (methods[method]) {
method = methods[method];
args = $.makearray(arguments).slice(1);
} else {
$.error('method ' + method + ' does not exist on tw.accordion');
return this;
}
return method.apply(this, args);
}
})(jquery);
.accordion {
margin:0;
padding:0;
font-size:14px;
}
.accordion > .accordion-header {
list-style: none;
margin: 0;
padding: 0;
border-bottom: 1px solid #ddd;
}
.accordion > .accordion-header.selected > .accordion-header-title {
color: #0094ff;
}
.accordion > .accordion-header > .accordion-header-title {
position: relative;
width: 100%;
height: 35px;
line-height: 35px;
background: #eee;
border-bottom: 1px solid #ccc;
cursor: pointer;
}
.accordion > .accordion-header > .accordion-header-title > i:first-child {
font-size: 1.3em;
}
.accordion > .accordion-header > .accordion-header-title > span {
position: relative;
top: -1px;
left: 5px;
}
.accordion > .accordion-header > .accordion-content {
display: none;
width: 100%;
height: calc(100% - 35px);
margin: 0;
padding: 0;
}
.accordion > .accordion-header.selected > .accordion-content {
display: block;
}
.accordion-content > .accordion-header {
list-style: none;
margin: 0;
padding: 0;
}
.accordion-content > .accordion-header.selected {
color: #0094ff;
}
.accordion-content > .accordion-header > .accordion-header-title {
position: relative;
width: 100%;
height: 32px;
line-height: 32px;
cursor: pointer;
border-bottom: 1px solid #ccc;
}
.accordion-content > .accordion-header > .accordion-header-title:hover {
background:#eee;
}
.accordion-content > .accordion-header > .accordion-header-title.selected {
color: #fff;
background: #0094ff;
border-left: 3px solid #ff6a00;
border-bottom: 0px;
}
.accordion-content > .accordion-header > .accordion-header-title > i:first-child {
font-size: 1.2em;
}
.accordion-content > .accordion-header > .accordion-header-title > span {
position: relative;
top: -1px;
left: 5px;
}
.accordion-content > .accordion-header > .accordion-header-title.selected > i:first-child {
position:relative;
left:-3px;
}
.accordion-content > .accordion-header > .accordion-header-title.selected > span {
position: relative;
top: -1px;
left: 2px;
}
.accordion-content > .accordion-header > .accordion-content {
display: none;
width: 100%;
height: calc(100% - 32px);
margin: 0;
padding: 0;
}
.accordion-content > .accordion-header.selected > .accordion-content {
display: block;
}