JSON无限折叠菜单编写实例


Posted in Javascript onDecember 16, 2013

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

下面我们来看看具体的效果如下:

JSON无限折叠菜单编写实例

下面我们来看看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样式可以自己下 没有关系!

JS代码如下:

/**
 * JSON无限折叠菜单
 * @constructor {AccordionMenu}
 * @param {options} 对象
 * @date 2013-12-13
 * @author tugenhua
 * @email 879083421@qq.com
 */
 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格式 然后引用我的css JS 也可以实现自己想要的效果 如果css上有自己的风格 也可以改写css样式!切忌!JSON格式一定要和我上面的一样 且名字也要叫一样的 就ok!初始化 如上

new AccordionMenu({menuArrs:testMenu}); 其中testMenu 就是上面定义的JSON格式。

Javascript 相关文章推荐
window.location和document.location的区别分析
Dec 23 Javascript
浅谈JavaScript编程语言的编码规范
Oct 21 Javascript
JavaScript新窗口与子窗口传值详解
Feb 11 Javascript
5种处理js跨域问题方法汇总
Dec 04 Javascript
jQuery中noConflict()用法实例分析
Feb 08 Javascript
vue2.0移除或更改的一些东西(移除index key)
Aug 28 Javascript
vue slot 在子组件中显示父组件传递的模板
Mar 02 Javascript
通过jquery.cookie.js实现记住用户名、密码登录功能
Jun 20 jQuery
vue中使用echarts制作圆环图的实例代码
Jul 27 Javascript
JS变量提升原理与用法实例浅析
May 22 Javascript
vue组件讲解(is属性的用法)模板标签替换操作
Sep 04 Javascript
Vue3+elementui plus创建项目的方法
Dec 01 Vue.js
使用JSLint提高JS代码质量方法分享
Dec 16 #Javascript
javascript操作table(insertRow,deleteRow,insertCell,deleteCell方法详解)
Dec 16 #Javascript
利用js动态添加删除table行的示例代码
Dec 16 #Javascript
js判断undefined类型,undefined,null, 的区别详细解析
Dec 16 #Javascript
innerHTML,outerHTML,innerText,outerText的用法及区别解析
Dec 16 #Javascript
js AppendChild与insertBefore用法详细对比
Dec 16 #Javascript
js中AppendChild与insertBefore的用法详细解析
Dec 16 #Javascript
You might like
PHP 5.3.1 安装包 VC9 VC6不同版本的区别是什么
2010/07/04 PHP
Yii结合CKEditor实现图片上传功能
2014/06/13 PHP
php通过sort()函数给数组排序的方法
2015/03/18 PHP
浅谈php中include文件变量作用域
2015/06/18 PHP
PHP实现多文件上传的方法
2015/07/08 PHP
修改jQuery.Autocomplete插件 支持中文输入法 避免TAB、ENTER键失效、导致表单提交
2009/10/11 Javascript
js 巧妙去除数组中的重复项
2010/01/25 Javascript
js去字符串前后空格5种实现方法及比较
2013/04/03 Javascript
两个select多选模式的选项相互移动(示例代码)
2014/01/11 Javascript
JavaScript控制两个列表框listbox左右交换数据的方法
2015/03/18 Javascript
JavaScript常用本地对象小结
2016/03/28 Javascript
jQuery ajax调用后台aspx后台文件的两种常见方法(不是ashx)
2016/06/28 Javascript
谈谈因Vue.js引发关于getter和setter的思考
2016/12/02 Javascript
微信小程序手势操作之单触摸点与多触摸点
2017/03/10 Javascript
JavaScript解析任意形式的json树型结构展示
2017/07/23 Javascript
关于预加载InstantClick的问题解决方法
2017/09/12 Javascript
ES6 javascript的异步操作实例详解
2017/10/30 Javascript
Vue自定义指令实现checkbox全选功能的方法
2018/02/28 Javascript
vue-router 源码实现前端路由的两种方式
2018/07/02 Javascript
微信小程序时间控件picker view使用详解
2018/12/28 Javascript
基于Taro的微信小程序模板消息-获取formId功能模块封装实践
2019/07/15 Javascript
jQuery实时统计输入框字数及限制
2020/06/24 jQuery
微信小程序对图片进行canvas压缩的方法示例详解
2020/11/12 Javascript
[04:55]完美世界副总裁蔡玮:DOTA2的自由、公平与信任
2013/12/18 DOTA
[01:24:34]2014 DOTA2华西杯精英邀请赛5 24 DK VS LGD
2014/05/25 DOTA
[49:35]LGD vs OG 2018国际邀请赛淘汰赛BO3 第二场 8.25
2018/08/29 DOTA
[01:06:54]DOTA2-DPC中国联赛 正赛 SAG vs DLG BO3 第二场 2月28日
2021/03/11 DOTA
Python获取脚本所在目录的正确方法
2014/04/15 Python
解决python写入mysql中datetime类型遇到的问题
2018/06/21 Python
解决pycharm 工具栏Tool中找不到Run manager.py Task的问题
2019/07/01 Python
纯css3制作网站后台管理面板
2014/12/30 HTML / CSS
xml有哪些解析技术?区别是什么
2016/04/26 面试题
丑小鸭教学反思
2014/02/03 职场文书
关于保护环境的建议书
2014/05/13 职场文书
技术股东合作协议书
2014/12/02 职场文书
个人思想政治总结
2015/03/05 职场文书