WordPress 多级导航菜单

来源:互联网 发布:php经典项目实例 源码 编辑:程序博客网 时间:2024/05/17 05:50

WordPress 多级导航菜单

多级导航菜单, 是指菜单存在多个层次, 层层嵌套, 当鼠标移动到某个菜单时, 如果其包含子菜单则将相应的子菜单显示出来. 本文将提供此功能在 WordPress 的实现方法, 一般的 HTML 页面和其他程序也可以加工套用.

Multi Level Menus

时隔 9 个多月, 关于导航菜单的话题又回来了. 上次写到三级菜单就不写了是因为我发现自己根本用不上, 就没去研究. 最近我在做一个小玩意儿用到了这个, 所以把它给做了出来并集成到 iNove 主题上. 因为内容繁多, 所以还是以之前的文章和代码作为基础来展开讲解, 希望这个文章会对大家有所帮助.

为了简化处理, 明确目标, 这次我们会以二级导航菜单作为原型进行扩展. 本文只对多级菜单相关处理进行讨论, 其他内容请参考以前的几篇关于菜单导航的文章, 文章链接你可以在本文相关话题中找到.

这是效果演示

相关话题:

WordPress 导航菜单
二级导航菜单
淡出淡入导航菜单
滚动导航菜单
jQuery 导航菜单
多级导航菜单
点选式导航菜单 (待定话题)

作业分析:

因为菜单由本来的二级菜单变成了多级菜单, 所以菜单结构会有些变化 (会有新的更深层的子菜单加入). 另外, 页面的样式和脚本都会有相应的变更, 重点在于对 JavaScript 的加工.

主要操作如下:
1. 鼠标移动到一级菜单的菜单项时, 如果该菜单项包含了二级菜单, 那么在下方显示其子菜单.
2. 鼠标移动到 N (N >= 2) 级菜单的菜单项时, 如果该菜单项包含了 N+1 级菜单, 那么在右侧显示其子菜单.

预想结构:

<div id="menubar"><ul class="menus"><li class="..."><a href="http://.../">Home</a></li><li class="..."><a href="http://.../">菜单1</a><ul class="children"><li class="..."><a href="http://.../">菜单11</a></li><li class="..."><a href="http://.../">菜单12</a><ul class="children"><li class="..."><a href="http://.../">菜单121</a></li><li class="..."><a href="http://.../">菜单122</a></li><li class="..."><a href="http://.../">菜单123</a></li><li class="..."><a href="http://.../">菜单124</a></li></ul></li><li class="..."><a href="http://.../">菜单13</a><ul class="children"><li class="..."><a href="http://.../">菜单131</a></li><li class="..."><a href="http://.../">菜单132</a></li></ul></li></ul></li><li class="..."><a href="http://.../">菜单2</a><ul class="children"><li class="..."><a href="http://.../">菜单21</a></li></ul></li><li class="..."><a href="http://.../">菜单3</a><ul class="children"><li class="..."><a href="http://.../">菜单31</a></li><li class="..."><a href="http://.../">菜单32</a><ul class="children"><li class="..."><a href="http://.../">菜单321</a></li><li class="..."><a href="http://.../">菜单322</a></li></ul></li></ul></li>...</ul></div>

实施操作:

1. 调出无限级菜单 (子分类)
是否还记得如何设定列表的深度? 可以通过参数 depth 来进行设定. 当我们将深度设为 1 时不显示子分类, 将深度设为 2 时显示二级菜单. 现在我们要无限制层数的菜单, 所以可以去除这个参数, 系统会自动返回所有菜单. 所以显示菜单的代码如下:

<?php wp_list_pages('depth=2&title_li=0&sort_column=menu_order'); ?>

2. 修改菜单的样式
在子菜单项添加 display:inline; 以免在 IE (IE6/IE7/IE8) 中发生错位.

/* 子菜单的菜单项 */#menubar ul.children li {float:none; /* 垂直排列 */margin:0;padding:0;/* multi 2009/06/11 ADD START */display:inline; /* 对 IE 来说十分很重要 *//* multi 2009/06/11 ADD END */}

追加包含子菜单的菜单项的样式

#menubar ul.children li a.subtitle {border-right:3px solid #4281B7;width:97px;}

添加当前菜单的效果, 以明确当前路径.

#menubar ul.menus li a:hover, /* multi 2009/06/11 ADD START */#menubar ul.menus li a.current {/* multi 2009/06/11 ADD END */background:#4281B7; /* 背景颜色 */}

3. 加载菜单
加载菜单是应该分开处理, 对于对层次的菜单, 菜单显示有两种状态. (1) 作为二级菜单显示在上一级菜单的下方; (2) 而三级和以上层次的菜单则会显示在上一级菜单的右侧.

// 找到所有的菜单var menus = this.obj.getElementsByTagName('ul');for (var i = 0; i < menus.length; i++) {// 找到菜单的父节点 (包括标题链接部分)var menu = menus[i].parentNode; // 如果菜单的父节点就是根菜单, 显示一般的菜单if(menu.parentNode === this.obj) {new Menu(menu, opacity); // 如果菜单的父节点不是根菜单, 说明当前菜单是子菜单} else {new Menu(menu, opacity, 1);// 在子菜单的标题链接上加上 class 名, 以便定义样式menu.firstChild.className += ' subtitle';}}

4. 菜单的初始化
添加一个参数, 以识别是否为子菜单 (三级以上的菜单); 去除 overflow:hidden; 的设置, 否则子菜单无法显示出来.

initialize: function(target, opacity, sub) {this.util = new MenuUtil(); // 获取目标菜单 (没多余元素)this.obj = this.util.cleanWhitespace(target); // 定义透明度, 默认透明this.opacity = opacity || 1; /* multi 2009/06/11 ADD START */// 是否为子菜单this.sub = sub || -1;/* multi 2009/06/11 ADD START */ // 获取菜单this.menu = this.obj.childNodes // 重要! 如果菜单不包含菜单项, 则不进行处理if (this.menu.length < 2) { return; } // 菜单标题和菜单体this.title = this.menu[0];this.body = this.menu[1]; // 定义初始样式this.util.setStyle(this.body, 'visibility', 'hidden');this.util.setStyle(this.body, 'position', 'absolute');/* multi 2009/06/11 DELETE START *///this.util.setStyle(this.body, 'overflow', 'hidden');/* multi 2009/06/11 DELETE END */this.util.setStyle(this.body, 'display', 'block'); // 添加监听器this.addListener(this.obj, 'mouseover', this.util.bind(this, this.activate), false);this.addListener(this.obj, 'mouseout', this.util.bind(this, this.deactivate), false);}

5. 对菜单和子菜单分开处理
菜单 (二级菜单) 的位置是相对于窗口的, 而子菜单 (三级或以上菜单) 是的位置是相对于上一级菜单的, 所以必须判断是哪种菜单类型, 并以不同的方法来确定位置. 另外, 两者要显示的位置也不相同, 所以在激活方法内还需要以不同的方式将 top 和 left 位置计算出来.

// 获取当前菜单体的位置 (子菜单)if(this.sub == 1) {var pos = this.util.currentOffset(this.title);var left = this.util.getWidth(this.body);var top = pos[1]; // 获取当前菜单体的位置 (菜单)} else {var pos = this.util.cumulativeOffset(this.title);var left = pos[0];var top = pos[1] + this.util.getHeight(this.title);// 子菜单不需要设置不透明度, 否则会形成多重透明, 效果不好.this.util.setStyle(this.body, 'opacity', this.opacity);}

6. 添加当前菜单的 className
为了更好的表示当前菜单的上级菜单, 在激活菜单的时候为当前菜单加上 className.

// 当前选中菜单加上 class 名为, 以便定义样式this.title.className += ' current';

并且在解除菜单的时候移除菜单上的 className.

// 离开菜单时取消当前菜单上的 class 名, 恢复原本的样式this.title.className = this.title.className.replace('current', '');

演示主题:

以 WordPress 自带主题 default 为基础, 仅做学习参考使用, 修改过的文件有 header.php 和 style.css, 添加了文件js/menu.js

下载主题: default_with_menubar_5.zip

原创粉丝点击