抠出淘宝的菜单树

淘宝登陆用户的纵向菜单树简洁大方,设计的很好,于是想趁闲暇时间将他的风格模仿下来,用在以后的网页中。

1、淘宝效果

淘宝 这个菜单树应该有很多人眼熟吧,它的一级菜单和二级菜单的折叠设计很简单,展示的效果却很舒服。适用于菜单层级只有3层的应用系统中。

2、寻找对应的css

从页面的源码中,可以找到对应的css文件,存放于

http://a.tbcdn.cn/tbsp/tbsp.css?t=20090602.css

http://a.tbcdn.cn/app/mytaobao/common_v2.css?t=20100505.css

两个文件中。如果不想将用到的css单独抠出来放在自己的网页中,完全可以引用这两个css路径,否则只有耐心寻找对应的样式,因为css类的分布很散乱。

还有一个页面级样式

 

1
2
3
4
html {overflow: hidden;}
    body {padding: 0;}
    .grid-c2 .col-sub {margin-left: 0;}
    #page, #content {width: 150px;overflow: hidden;margin-left: 0;}

 

注意css中引用的图标要从淘宝上拿过来,不然本地的css也会没图的,地址是:

http: //a.tbcdn.cn/app/mytaobao/v4/img/mytaobao_v4_bg.png

3、加入JavaScript

淘宝中使用的JavaScript中引用了Yahoo的js库,我不想为了一个菜单在单独引用一个库,就把js代码全部改成jquery了。你也可以原封不动引用淘宝的js脚本地址:

http://a.tbcdn.cn/app/mytaobao/common_v2.js?t=20100505.js

http://a.tbcdn.cn/tbra/1.0/tbra-aio.js?t=20090604.js

还有一个页面脚本

 

1
2
3
4
5
6
7
8
9
10
11
12
13
window.onload = function() {
    var Y = YAHOO.util, D = Y.Dom, E = Y.Event, oPage, oIframe;
    document.domain = TB.bom.pickDocumentDomain();
    oPage = D.get('page');
    oIframe = parent.document.getElementById('J_MenuFrame');
    if (!oIframe) {return;}
    function setHeight() {
        D.setStyle(oIframe, 'height', oPage.offsetHeight + 'px');
    };
    // onActivate
    mytaobao.group.callback.onActivate.subscribe(setHeight);
    mytaobao.group.callback.onDeactivate.subscribe(setHeight);
    setHeight();

 

4、生成菜单的JavaScript方法封装

1
2
3
4
5
6
7
8
9
10
11
12
13
function MakeMenu()
{
    // 考虑将来扩展到frame任意定位菜单,需要指定document和document.body
    var menuDoc=document;
    var menuBody=document.body;
    var menuDiv=$("#page",menuBody);
     
    if(menuDiv.length==0)
    {
        menuDiv=$("<div id='page'><div id='coolMenu-panel' class='grid-c2'><div class='box-diamond' id='coolMenu-menu'><div class='coolMenu-bd' id='menuPad'></div></div></div></div>");
        $(menuBody).append(menuDiv);
    }
}

 

需要在页面上生成一个外层包裹菜单的容器层“page”,层级间的结构仿照淘宝的结构做,这样对css的改动就小了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
function AddMenu(selfMenuID,selfMenuText,selfMenusrc,parentMenuID,srcTarget)
{
    // 考虑将来扩展到frame任意定位菜单,需要指定document和document.body
    var menuDoc=document;
    var menuBody=document.body;
     
    var menuPad=$("#menuPad",menuBody);
    if(menuPad.length==0)
    {
        MakeMenu();
        menuPad=$("#menuPad",menuBody);
    }
 
    var strInnerMenu; // 拼接菜单的html串
    var parentMenu=$("\"#menu_"+parentMenuID+"\"",menuBody);
    if(parentMenu.length==0)  // 一级菜单
    {
        strInnerMenu="<div class='menu-box' id='menu_"+selfMenuID+"'><h3 class='coolMenu-bar'><span>"+selfMenuText+"</span><button class='menu-close'>-</button></h3></div>";
        menuPad.append(strInnerMenu);
    }
    else if(parentMenu.attr("class")=="menu-box"// 二级菜单
    {
        strInnerMenu="<li id='menu_"+selfMenuID+"'><span><a href='"+selfMenusrc+"' target='"+srcTarget+"'>"+selfMenuText+"</a></span></li>";
        var S_ul=$("\"#ul_"+parentMenuID+"\"",menuBody);
        if(S_ul.length==0)
        {
            S_ul=$("<ul class='group' id='ul_"+parentMenuID+"'></ul>");
            parentMenu.append(S_ul);   
        }
        S_ul.append(strInnerMenu);
    }
    else  // 三级以下菜单
    {
        strInnerMenu="<li id='menu_"+selfMenuID+"'><a href='"+selfMenusrc+"' target='"+srcTarget+"'>"+selfMenuText+"</a></li>";
        var T_ul=$("\"#ul_"+parentMenuID+"\"",menuBody);
        if(T_ul.length==0)
        {
            T_ul=$("<ul id='ul_"+parentMenuID+"'></ul>");
            parentMenu.append(T_ul);   
            parentMenu.addClass("fold-open");
            parentMenu.find("span:first").attr("id","T_span");
        }
        T_ul.append(strInnerMenu);
    }  
 
}

AddMenu是真正的核心方法,通过它将一级级的菜单加入到树中,并应用对应的css。个参数含义:

selfMenuID:当前菜单编号,

selfMenuText:当前菜单名称,

selfMenusrc:当前菜单url,

parentMenuID:父菜单编号,

srcTarget:地址跳转类型,空白页_blank或frame名称。

实现思路就是:如果当前菜单的父菜单不存在,就是一级菜单;如果父菜单存在并且css类时menu-box,则当前是二级菜单,否则是三级菜单。

正因为这样的实现思路,要求只能有三级菜单,否则三级后面的就平级了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function BindEclipseFun()
{
 
    $("span[id='T_span']").toggle(
        function()
        {
            $(this).parents("li").removeClass("fold-open").addClass("fold-close");
        },
        function()
        {
            $(this).parents("li").removeClass("fold-close").addClass("fold-open");
        }
    );
 
    $("h3[class='coolMenu-bar']").toggle(
        function()
        {  
            $(this).next("ul:first").addClass("hidden");
            $(this).find("button").removeClass("menu-close").addClass("menu-open");
        },
        function()
        {
            $(this).next("ul:first").removeClass("hidden");
            $(this).find("button").removeClass("menu-open").addClass("menu-close");
        }
    ); 
 
}

BindEclipseFun方法是给生成的菜单增加样式和事件的,在单击父级菜单时切换折叠和展开效果都是通过css样式的切换实现的。

 

5、使用小例

在页面的初始化脚本中加入以下代码,就能生成一个淘宝样式的菜单树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$(function() {
                AddMenu('1','系统管理','','0','_blank');
                AddMenu('2','常用操作','','0','_blank');
                AddMenu('3','网上支付','','0','_blank');
                AddMenu('4','用户管理','user.aspx','1','_blank');
                AddMenu('5','部门管理','dept.aspx','1','_blank');
                AddMenu('6','省级用户','supuser.aspx','4','_blank');
                AddMenu('7','地级用户','comuser.aspx','4','_blank');
                AddMenu('8','账户查询','payCheck.aspx','2','_blank');      
                AddMenu('9','银联支付','unipay.aspx','3','_blank');
                AddMenu('9','主账户查询','master.aspx','8','_blank');
                AddMenu('10','子账户查询','sub.aspx','8','_blank');
                BindEclipseFun();
            });

 

页面效果

display

6、注意事项

html页面必须引用了jquery的库;

菜单只能有三级;

增加菜单时,即调用AddMenu方法时,必须一层一层调用,也就是说必须先添加一级菜单,然后添加二级菜单,最后添加三级菜单。这样的数据处理很简单,嵌套几个循环或者用迭代就可以选择出来分级的数据。

源码下载:http://cid-8e164418a642ea96.office.live.com/self.aspx/.Public/taobaoMenu.rar

备用下载

欢迎转载,但请注明出处

posted @   混世者  阅读(4185)  评论(39编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示