您的位置:首页 > Web前端 > JavaScript

JSON版无限折叠菜单

2015-12-05 01:34 633 查看
最近看了一篇关于JSON无限折叠菜单的文章,感觉写的不错,也研究一了下他的代码,所以自己也做了个Demo,其实这样的菜单项是我们网站上或者项目导航菜单项很常见的一种效果,特别是在一些电子商务网站上的左上方部分,或者说导航菜单有下拉效果也是很常见的,但是他们都是做成了固定的,也就是页面上代码直接写死的,然后实现这种下拉效果。而今天我们是通过JSON格式来自动生成的,或者可以说,要做这种折叠菜单效果,只需要开发人员提供我们前端这种JSON格式或者我们前端可以搞定这种格式,其他的都可以直接引用这个代码进去就可以了。下面给大家来分享下我的JavaScript代码!

我们来看看具体的效果:



再来看看JSON格式:

var testMenu=[
{
"name": "一级菜单",
"submenu": [
{
"name": "二级菜单",
"url": ""
},
{
"name": "二级菜单",
"url": ""
}
]
},
{
"name": "一级菜单",
"submenu": [
{
"name": "二级菜单",
"url": ""
},
{
"name": "二级菜单",
"submenu": [
{
"name": "三级菜单",
"submenu": [
{
"name": "四级菜单",
"url": ""
}
]
},
{
"name": "三级菜单",
"url": ""
}
]
},
{
"name": "二级菜单",
"url": ""
},
{
"name": "二级菜单",
"submenu": [
{
"name": "三级菜单",
"submenu": [
{
"name": "四级菜单",
"url": ""
},
{
"name": "四级菜单",
"submenu": [
{
"name": "五级菜单",
"url": ""
},
{
"name": "五级菜单",
"url": ""
}
]
}
]
},
{
"name": "三级菜单",
"url": ""
}
]
},
{
"name": "二级菜单",
"url": ""
}
]
},
{
"name": "一级菜单",
"submenu": [
{
"name": "二级菜单",
"url": ""
},
{
"name": "二级菜单",
"url": ""
},
{
"name": "二级菜单",
"url": ""
}
]
}
];


只要这种JSON格式就OK了,且上面的参数名使用name submenu url就可以了,然后页面中的HTML格式如下:

<div class="wrap-menu"></div>


CSS代码如下:

<style type="text/css">
.wrap-menu { overflow:auto; width:300px; background:#F6F6F6; font:12px/1.5 Tahoma,Arial,sans-serif}
.wrap-menu ul{ list-style:none; margin:0; padding:0;}
.wrap-menu ul li{ text-indent:3em; white-space:nowrap; }
.wrap-menu ul li h2{ cursor:pointer; height:100%; width:100%; margin:0 0 1px 0; font:12px/31px '宋体'; color:#fff; background:red;}
.wrap-menu ul li a{ display:block; outline:none; height:25px; line-height:25px; margin:1px 0; color:#1A385C; text-decoration:none;}
.wrap-menu ul li img{ margin-right:10px; margin-left:-17px; margin-top:9px; width:7px; height:7px; background:url(images/arrow.gif) no-repeat; border:none;}
.wrap-menu ul li img.unfold{ background-position:0 -9px;}
.wrap-menu ul li a:hover{ background-color:#ccc; background-image:none;}
</style>


CSS样式可以自己随意定义,我这里是简单的效果!

JavaScript代码如下:

/**
* JSON无限折叠菜单
* @constructor {AccordionMenu}
* @param {options} 对象
*/

function AccordionMenu(options) {
this.config = {
containerCls        : '.wrap-menu',                // 外层容器
menuArrs            :  '',                         //  JSON传进来的数据
type                :  'click',                    // 默认为click 也可以mouseover
renderCallBack      :  null,                       // 渲染html结构后回调
clickItemCallBack   : null                         // 每点击某一项时候回调
};
this.cache = {

};
this.init(options);
}

AccordionMenu.prototype = {

constructor: AccordionMenu,

init: function(options){
this.config = $.extend(this.config,options || {});
var self = this,
_config = self.config,
_cache = self.cache;

// 渲染html结构
$(_config.containerCls).each(function(index,item){

self._renderHTML(item);

// 处理点击事件
self._bindEnv(item);
});
},
_renderHTML: function(container){
var self = this,
_config = self.config,
_cache = self.cache;
var ulhtml = $('<ul></ul>');
$(_config.menuArrs).each(function(index,item){
var lihtml = $('<li><h2>'+item.name+'</h2></li>');

if(item.submenu && item.submenu.length > 0) {
self._createSubMenu(item.submenu,lihtml);
}
$(ulhtml).append(lihtml);
});
$(container).append(ulhtml);

_config.renderCallBack && $.isFunction(_config.renderCallBack) && _config.renderCallBack();

// 处理层级缩进
self._levelIndent(ulhtml);
},
/**
* 创建子菜单
* @param {array} 子菜单
* @param {lihtml} li项
*/
_createSubMenu: function(submenu,lihtml){
var self = this,
_config = self.config,
_cache = self.cache;
var subUl = $('<ul></ul>'),
callee = arguments.callee,
subLi;

$(submenu).each(function(index,item){
var url = item.url || 'javascript:void(0)';

subLi = $('<li><a href="'+url+'">'+item.name+'</a></li>');
if(item.submenu && item.submenu.length > 0) {

$(subLi).children('a').prepend('<img src="images/blank.gif" alt=""/>');
callee(item.submenu, subLi);
}
$(subUl).append(subLi);
});
$(lihtml).append(subUl);
},
/**
* 处理层级缩进
*/
_levelIndent: function(ulList){
var self = this,
_config = self.config,
_cache = self.cache,
callee = arguments.callee;

var initTextIndent = 2,
lev = 1,
$oUl = $(ulList);

while($oUl.find('ul').length > 0){
initTextIndent = parseInt(initTextIndent,10) + 2 + 'em';
$oUl.children().children('ul').addClass('lev-' + lev)
.children('li').css('text-indent', initTextIndent);
$oUl = $oUl.children().children('ul');
lev++;
}
$(ulList).find('ul').hide();
$(ulList).find('ul:first').show();
},
/**
* 绑定事件
*/
_bindEnv: function(container) {
var self = this,
_config = self.config;

$('h2,a',container).unbind(_config.type);
$('h2,a',container).bind(_config.type,function(e){
if($(this).siblings('ul').length > 0) {
$(this).siblings('ul').slideToggle('slow').end().children('img').toggleClass('unfold');
}

$(this).parent('li').siblings().find('ul').hide()
.end().find('img.unfold').removeClass('unfold');
_config.clickItemCallBack && $.isFunction(_config.clickItemCallBack) && _config.clickItemCallBack($(this));

});
}
};


代码初始化方式如下:

$(function(){
new AccordionMenu({menuArrs:testMenu});
});


大家可以自己定义上面的JSON格式,然后引用我的JavaSript,也可以改写CSS样式!JSON格式一定要和我上面的一样,且名字要一样!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: