以JavaScript来实现WordPress中的二级导航菜单的方法
导航
菜单早已 "深入民心",在
博客上的应用日益重要且多样. 从本文开始,我将开展几个关于
wordpress 导航
菜单的话题,讨论如何在
wordpress 上使用和加强导航
菜单,话题间有一定的承接关系,难度也会逐步
增加.
wordpress 上的导航菜单一般有两种,页面导航菜单和分类导航菜单.
可曾记得? wordpress 是可以撰写独立页面的,页面导航菜单就是以首页和各个独立页面组成的菜单. 而分类导航菜单则是以首页和各个分类组成的菜单.
既然菜单由首页和独立页面列表或首页和分类列表所组成,我们就需要处理两个环节,即首页菜单项和其他菜单项.
另外,我们还需要处理菜单项的三个状态,即一般状态,当前菜单项状态 (如: 在首页中,首页菜单项就是当前菜单项) 和选中菜单项状态.
也就是说,我们共需要处理 3 个事情:
1. 首页外的其他菜单项
2. 首页菜单项
3. 菜单项处于不同状态时的视觉效果
预想结构:
页面导航菜单
1. 独立页面列表作为菜单项
调用 wp_list_pages 获取独立页面列表,并使用以下参数:
depth: 列表深度(层的最大数量),本文讨论的是一级菜单,故最大深度为 1
title_li: 标题字符串,这里不需要,设为 0
sort_column: 列表项的排序方式,根据创建页面时所设定的 order 进行升序排列
打印独立页面菜单项的语句是:
2. 首页菜单项
由于一般独立页面的 class 是 page_item,当前独立页面的 class 是 current_page_item. 当页面是首页时,首页菜单项的 class 应该是 current_page_item,其他情况则是 page_item. 为此,我们需要一段分支代码来为它确定 class:
// 如果是首页,class 是 current_page_item
if (is_home()) {
$home_menu_class = 'current_page_item';
// 如果不是首页,class 是 page_item
} else {
$home_menu_class = 'page_item';
}
?>
打印首页菜单项的语句是:
3. 菜单的样式
这是一个从普遍到特殊的处理过程,一般菜单项的样式放前面,当前和选中菜单项的样式放在后面,当后者条件满足就会覆盖前者的样式,从而改变外观.
PHP;">
/*
菜单项 */
#menubar ul.menus li {
float:left; /* 靠左浮动 */
list-style:none; /* 清空列表风格 */
margin-right:1px; /* 右侧的间隔 */
}
/*
菜单项
链接 */
#menubar ul.menus li a {
padding:5px 10px; /* 内边距 */
display:block; /*
显示为块 */
color:#FFF; /*
文字颜色 */
background:#67ACE5; /* 背景颜色 */
text-decoration:none; /* 没有下横线 */
}
/* 当前
菜单项
链接 */
#menubar ul.menus li.current_page_item a {
background:#5495CD; /* 背景颜色 */
}
/* 选中
菜单项
链接 */
#menubar ul.menus li a:hover {
background:#4281B7; /* 背景颜色 */
}
1. 分类列表作为菜单项
调用方法 wp_list_categories 获取分类列表,设为 0
orderby: 列表项的排序方式,根据创建页面时所设定的 order 进行升序排列
show_count: 是否显示该分类的文章数量,这里不需要显示,设为 0
打印分类菜单项的语句是:
PHP;">
2. 首页菜单项
与页面导航菜单相似,只是菜单项的 class 有所不同.
page_item 更改为 cat-item
current_page_item 更改为 current-cat
3. 菜单的样式
因为菜单项的 class 略有不同,所以也需稍作修改.
current_page_item 更改为 current-cat
我们已经知道菜单如何创建了,这回我们要使用分类列表做成二级导航菜单. 我们要做的其实是在原有的基础上改出二级菜单,以及对二级菜单进行处理. (请确保的的分类中包含子分类,否则调不出二级菜单.)
我们共需要处理 3 个事情:
1. 调出二级菜单 (子分类)
2. 二级菜单的样式
3. 二级菜单的效果
预想结构
Author: mg12
Feature: MenuList with second-level menus
Update: 2008/08/30
Tutorial URL:
http://www.neoease.com/wordpress-menubar-2/
*/
/* 类 /
var Class = {
create: function() {
return function() {
this.initialize.apply(this,arguments);
}
}
}
/* 菜单列表 /
var MenuList = Class.create();
MenuList.prototype = {
/**
- 构造方法
- id: 菜单列表
- opacity: 透明度 (0.0 - 1.0,0.0 为全透明,1.0 为不透明)
*/
initialize: function(id,opacity) {
// 获取菜单列表
this.obj = document.getElementById(id);
if (!this.obj) { return; }
// 对菜单列表内的所有菜单进行处理
var menus = this.obj.childNodes;
for (var i = 0; i < menus.length; i++) {
var menu = menus[i];
if (menu.tagName == 'LI') {
// 构建菜单
new Menu(menu,opacity);
}
}
}
}
/* 菜单 /
var Menu = Class.create();
Menu.prototype = {
/**
- 构造方法
- target: 目标菜单
- opacity: 透明度 (0.0 - 1.0,1.0 为不透明)
*/
initialize: function(target,opacity) {
this.util = new MenuUtil();
// 获取目标菜单 (没多余元素)
this.obj = this.util.cleanWhitespace(target);
// 定义透明度,默认为不透明
this.opacity = opacity || 1;
// 获取菜单
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');
this.util.setStyle(this.body,'overflow','display','block');
// 添加监听器
this.addListener(this.obj,'mouSEOver',this.util.bind(this,this.activate),false);
this.addListener(this.obj,'mouSEOut',this.deactivate),false);
},/**
- 激活方法
- 当鼠标移动到菜单标题是激活
*/
activate: function() {
// 获取当前菜单体的位置
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,'left',left + 'px');
this.util.setStyle(this.body,'top',top + 'px');
this.util.setStyle(this.body,'visible');
this.util.setStyle(this.body,'opacity',this.opacity);
this.util.setStyle(this.body,'filter','alpha(opacity=' + this.opacity * 100 + ')');
},/**
- 解除方法
- 当鼠标移动出菜单标题是激活
*/
deactivate: function(){
// 定义解除时样式
this.util.setStyle(this.body,'hidden');
},/**
- 监听方法
- element: 监听对象
- name: 监听方法
- observer: 执行的方法
- useCapture: 浏览器调用事件的方式 (true 为 Capture 方式,false 为 Bubbling 方式)
*/
addListener: function(element,name,observer,useCapture) {
if(element.addEventListener) {
element.addEventListener(name,useCapture);
} else if(element.attachEvent) {
element.attachEvent('on' + name,observer);
}
}
}
/* 一些实用的方法 /
var MenuUtil = Class.create();
MenuUtil.prototype = {
initialize: function() {
},$: function(id) {
return document.getElementById(id);
},$A: function(iterable) {
if(!iterable) {
return [];
}
if(iterable.toArray) {
return iterable.toArray();
} else {
var results = [];
for(var i = 0; i < iterable.length; i++) {
results.push(iterable[i]);
}
return results;
}
},bind: function() {
var array = this.$A(arguments);
var func = array[array.length - 1];
var _method = func,args = array,object = args.shift();
return function() {
return _method.apply(object,args.concat(array));
}
},getHeight: function(element) {
return element.offsetHeight;
},setStyle: function(element,key,value) {
element.style[key] = value;
},getStyle: function(element,key) {
return element.style[key];
},cleanWhitespace: function(list) {
var node = list.firstChild;
while (node) {
var nextNode = node.nextSibling;
if(node.nodeType == 3 && !/\S/.test(node.nodeValue)) {
list.removeChild(node);
}
node = nextNode;
}
return list;
},cumulativeOffset: function(element) {
var valueT = 0,valueL = 0;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
element = element.offsetParent;
} while (element);
return [valueL,valueT];
}
}
/* 添加到页面加载事件 /
window.onload = function(e) {
new MenuList('menus',0.9);
}