DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> 以JavaScript來實現WordPress中的二級導航菜單的方法
以JavaScript來實現WordPress中的二級導航菜單的方法
編輯:關於JavaScript     

導航菜單
導航菜單早已 "深入民心", 在博客上的應用日益重要且多樣. 從本文開始, 我將開展幾個關於 WordPress 導航菜單的話題, 討論如何在 WordPress 上使用和加強導航菜單, 話題間有一定的承接關系, 難度也會逐步增加.

20151214144601612.png (266×24)

WordPress 上的導航菜單一般有兩種, 頁面導航菜單和分類導航菜單.
可曾記得? WordPress 是可以撰寫獨立頁面的, 頁面導航菜單就是以首頁和各個獨立頁面組成的菜單. 而分類導航菜單則是以首頁和各個分類組成的菜單.
這是效果演示
既然菜單由首頁和獨立頁面列表或首頁和分類列表所組成, 我們就需要處理兩個環節, 即首頁菜單項和其他菜單項.
另外, 我們還需要處理菜單項的三個狀態, 即一般狀態, 當前菜單項狀態 (如: 在首頁中, 首頁菜單項就是當前菜單項) 和選中菜單項狀態.
也就是說, 我們共需要處理 3 個事情:
1. 首頁外的其他菜單項
2. 首頁菜單項
3. 菜單項處於不同狀態時的視覺效果

預想結構:

<div id="menubar">
 <ul class="menus">
 <li class="..."><a href="http://.../">Home</a></li>
 <li class="..."><a href="http://.../">菜單項1</a></li>
 <li class="..."><a href="http://.../">菜單項2</a></li>
 <li class="..."><a href="http://.../">菜單項3</a></li>
 ...
 </ul>
</div>

頁面導航菜單

1. 獨立頁面列表作為菜單項
調用 wp_list_pages 獲取獨立頁面列表, 並使用以下參數:
depth: 列表深度(層的最大數量), 本文討論的是一級菜單, 故最大深度為 1
title_li: 標題字符串, 這裡不需要, 設為 0
sort_column: 列表項的排序方式, 根據創建頁面時所設定的 order 進行升序排列
打印獨立頁面菜單項的語句是:

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

2. 首頁菜單項
由於一般獨立頁面的 class 是 page_item, 當前獨立頁面的 class 是 current_page_item. 當頁面是首頁時, 首頁菜單項的 class 應該是 current_page_item, 其他情況則是 page_item. 為此, 我們需要一段分支代碼來為它確定 class:

<?php
 
// 如果是首頁, class 是 current_page_item
if (is_home()) {
 $home_menu_class = 'current_page_item';
// 如果不是首頁, class 是 page_item
} else {
 $home_menu_class = 'page_item';
}
 
?>

打印首頁菜單項的語句是:

<li class="<?php echo($home_menu_class); ?>">
 <a title="Home" href="<?php echo get_settings('home'); ?>/">Home</a>
</li>

3. 菜單的樣式
這是一個從普遍到特殊的處理過程, 一般菜單項的樣式放前面, 當前和選中菜單項的樣式放在後面, 當後者條件滿足就會覆蓋前者的樣式, 從而改變外觀.

/* 菜單項 */
#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 獲取分類列表, 並使用以下參數:
depth: 列表深度(層的最大數量), 本文討論的是一級菜單, 故最大深度為 1
title_li: 標題字符串, 這裡不需要, 設為 0
orderby: 列表項的排序方式, 根據創建頁面時所設定的 order 進行升序排列
show_count: 是否顯示該分類的文章數量, 這裡不需要顯示, 設為 0
打印分類菜單項的語句是:

<?php wp_list_categories('depth=1&title_li=0&orderby=name&show_count=0'); ?>

2. 首頁菜單項
與頁面導航菜單相似, 只是菜單項的 class 有所不同.
page_item 更改為 cat-item
current_page_item 更改為 current-cat

3. 菜單的樣式
因為菜單項的 class 略有不同, 所以也需稍作修改.
current_page_item 更改為 current-cat


二級導航菜單

20151214144739496.png (460×160)

我們已經知道菜單如何創建了, 這回我們要使用分類列表做成二級導航菜單. 我們要做的其實是在原有的基礎上改出二級菜單, 以及對二級菜單進行處理. (請確保的的分類中包含子分類, 否則調不出二級菜單.)
我們共需要處理 3 個事情:
1. 調出二級菜單 (子分類)
2. 二級菜單的樣式
3. 二級菜單的效果

預想結構

<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://.../">菜單項1</a></li>
  <li class="..."><a href="http://.../">菜單項2</a></li>
  <li class="..."><a href="http://.../">菜單項3</a></li>
  </ul>
 </li>
 <li class="...">
  <a href="http://.../">菜單2</a>
  <ul class="children">
  <li class="..."><a href="http://.../">菜單項4</a></li>
  </ul>
 </li>
 <li class="...">
  <a href="http://.../">菜單3</a>
  <ul class="children">
  <li class="..."><a href="http://.../">菜單項5</a></li>
  <li class="..."><a href="http://.../">菜單項6</a></li>
  </ul>
 </li>
 ...
 </ul>
</div>

實施操作

1. 調出二級菜單 (子分類)
是否還記得制作導航菜單時是如何設定列表深度的? 當時將深度設為 1 是為了不顯示子分類, 現在要二級子分類當然要將深度設為 2 了.
depth: 列表深度(層的最大數量), 本文討論的是二級菜單, 故最大深度為 2.
打印分類菜單項的語句是:

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

2. 二級菜單的樣式
也只是在本來的樣式上進行修改, 加上子分類的樣式.

/* 二級菜單 */
#menubar ul.children {
 display:none; /* 初始化頁面時不顯示出來 */
 padding:0;
 margin:0;
}
/* 二級菜單的菜單項 */
#menubar ul.children li {
 float:none; /* 垂直排列 */
 margin:0;
 padding:0;
}
/* 二級菜單的當前菜單項鏈接 */
#menubar ul.children li a {
 width:100px; /* 對 IE6 來說十分很重要 */
}

打印首頁菜單項的語句是:

<li class="<?php echo($home_menu_class); ?>">
 <a title="Home" href="<?php echo get_settings('home'); ?>/">Home</a>
</li>

3. 二級菜單的效果
全部使用 JavaScript 實現, 為便於理解, 使用面向對象方式編寫代碼, 借鑒了部分 Prototype 框架的代碼. 因為代碼比較多, 不適合逐句解說, 所以我已標上了大量注釋. 代碼不是很復雜, 有 JS 基礎的話應該不會存在障礙.
另外為了迎合個別人的口味, 加上透明效果. Enjoy!

/*
 
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, 0.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', 'hidden');
 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);
 },
 
 /**
 * 激活方法
 * 當鼠標移動到菜單標題是激活
 */
 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, 'visibility', '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, 'visibility', 'hidden');
 },
 
 /**
 * 監聽方法
 * element: 監聽對象
 * name: 監聽方法
 * observer: 執行的方法
 * useCapture: 浏覽器調用事件的方式 (true 為 Capture 方式, false 為 Bubbling 方式)
 */
 addListener: function(element, name, observer, useCapture) {
 if(element.addEventListener) {
  element.addEventListener(name, observer, 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);
}

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved