昨天下午有同學問了一個很有趣的選單效果,它的子母選單都是水平式排列,當滑鼠移到母選單時,才會展開子選單。其中最有趣的是子選單的背景顏色會隨著母選單的第一字的顏色而改變,所以筆者就花點時間來實作出來跟大家分享一下。
檢視原始碼 HTML
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 | <body> <div id="menu-wrapper"> <div class="main-menu-wrapper"> <div class="main-menu"> <ul> <li class="m1"><a href="#"><span>j</span>Query</a></li> <li class="m2"><a href="#"><span>A</span>ndroid</a></li> <li class="m3"><a href="#"><span>W</span>ordPress</a></li> <li class="m4"><a href="#"><span>O</span>penCart</a></li> </ul> </div> </div> <div class="sub-menu-wrapper"> <div class="sub-menu"> <ul class="sub-memu-0"> <li><a href="#">jQuery 應用</a></li> <li><a href="#">jQuery 外掛</a></li> <li><a href="#">jQuery 技巧</a></li> <li><a href="#">jQuery 資源</a></li> </ul> <ul class="sub-memu-1"> <li><a href="#">Android 程式片段</a></li> <li><a href="#">推薦 APP</a></li> <li><a href="#">新機介紹</a></li> </ul> <ul class="sub-memu-2"> <li><a href="#">WP 外掛</a></li> <li><a href="#">WP 技巧</a></li> </ul> <ul class="sub-memu-3"> <li><a href="#">OP 外掛</a></li> <li><a href="#">OP 主題</a></li> </ul> </div> </div> </div> </body> |
.main-menu 主要是母選單,而 .sub-memu-0 就是相對應的子選單。那為什麼要用一堆區塊包起來呢?快先來看 CSS 吧;
檢視原始碼 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 47 48 49 50 51 52 | body { margin: 0; } #menu-wrapper .main-menu , #menu-wrapper .sub-menu { margin: 0 auto; width: 980px; } #menu-wrapper ul, #menu-wrapper ul li { margin: 0; padding: 0; list-style: none; } .main-menu ul li, .sub-menu ul li { float: left; } .main-menu ul li a { color: #000; display: block; margin-right: 50px; padding: 5px 5px 5px 0; text-decoration: none; } .sub-menu-wrapper { height: 28px; clear: left; background-color: #f90; border-top: 5px solid #f90; /* 預設使用跟 .c1 一樣的顏色 */ } .sub-menu { height: 28px; position: relative; overflow: hidden; } .sub-menu ul { position: absolute; } .sub-menu ul li a { color: #fff; display: block; margin-right: 20px; padding-top: 2px; text-decoration: none; } /* 自訂子選單的位置 */ .sub-menu .sub-memu-1 { left: 50px; } .sub-menu .sub-memu-2 { left: 170px; } .sub-menu .sub-memu-3 { left: 265px; } /* 自訂每一個選單的顏色 */ .main-menu ul li.m1 span, .main-menu ul li.m1 a.selected { color: #f90; } .main-menu ul li.m2 span, .main-menu ul li.m2 a.selected { color: #09c; } .main-menu ul li.m3 span, .main-menu ul li.m3 a.selected { color: #3c0; } .main-menu ul li.m4 span, .main-menu ul li.m4 a.selected { color: #f6f; } |
CSS 並沒用到什麼特殊的語法,咱們就直接來看套上去後的效果吧~
雖然現在子選單們都疊在一起了,但這就是 jQuery 出場的時機:
檢視原始碼 JavaScript
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 47 48 49 | $(function(){ // 先取得相關選單元素及高度 var $menuWrapper = $('#menu-wrapper'), $subMenuWwrapper = $menuWrapper.find('.sub-menu-wrapper').add($menuWrapper.find('.sub-menu')), _height = $subMenuWwrapper.height(), _animateSpeed = 200; // 先把 $subMenuWwrapper 的高度歸 0 // 並把 .sub-menu ul 先往上移動隱藏 var $subMenu = $subMenuWwrapper.height(0).find('.sub-menu ul').css({ top: _height * -1 }); // 當滑鼠移入到 .main-menu ul li a 上時 $('.main-menu ul li a').mouseover(function(){ // 先取出被滑鼠移入的選單 // 並取得該選單中第一個 span 的文字顏色 var $this = $(this), $color = $this.find('span').css('color'), _no = $this.parent().index(); // 改變 $subMenuWwrapper 的顏色為 $color 並展開高度 $subMenuWwrapper.css({ backgroundColor: $color, borderTopColor: $color }).stop().animate({ height: _height }, _animateSpeed); // 移動相對應的子選單 $subMenu.eq(_no).stop().animate({ top: 0 }, _animateSpeed).siblings().stop().animate({ top: _height * -1 }, _animateSpeed); // 讓被滑鼠移入的選單加上指定的效果 $this.addClass('selected').parent().siblings().find('a.selected').removeClass('selected'); return false; }); // 當滑鼠移出 $menuWrapper 後把 $subMenuWwrapper 的高度歸 0 $menuWrapper.mouseleave(function(){ $subMenuWwrapper.stop().animate({ height: 0 }, _animateSpeed); }); }); |
把子選單藏起來或是顯示子選單的動作都由程式來控制,當滑鼠移到母選單時就會自動展開子選單囉~
沙發!!
大大, 我用Opera右鍵查看了source code, 也可以改成你po的效果.. 但怎樣把這三個(html + css + java)放個合適的backend文件位置上?
FTP上傳我會, 但該放哪/改哪?
對不起, 如果答案太複雜或長篇, 大大可能要另寫一文了 ..
先謝謝大大抽空閱讀我的疑問
可以預設某一個母選單預設為顯示嗎?
是可以的。但這樣當滑鼠移出區塊時, 可能就不適合搭配縮小的功能了。
大大,
我想請問我在做網站的時候
上方的導覽按鈕也是使用水平子母選單
導覽下方使用廣告輪播圖片的語法
但是子選單會被輪播圖片擋住
我將子母選單的position設為absolute之後
雖然子選單不會被擋住了
但用ie瀏覽選單卻會整個歪掉! 不在正中間了!(用chrome和firefox都正常縮)
不管我怎麼調其他數值都還是歪掉!
請問有甚麼方法可以解決嗎??
謝謝你!!!
你可以先試著把你的選單的 z-indx 設的比廣告區塊還要高。
哈囉老師您好,
請問這個兩個範例如果要把整個選單置中要在哪裡加入css呢?
因為我把裡面float:left改為middle整個會跑掉耶,
我想把整個選單在螢幕的最中間,
這兩個範例好像都是靠左對齊,
可以請您指點一下,
3Q!!
float 有 middle 這值麽XD
常見的置中除了用 text-align 外, 再來就是使用 margin: 0 auto; 囉!!
好想要知道"判斷是否有子選單,若沒有時則不改變高度"QQ
不太懂js..所以土法煉鋼按照上面的js做..
第一格沒有子選單:
$('li.m1 a').mouseover(function(){
$subMenuWwrapper.stop().animate({
height: 0
}, _animateSpeed);
});
不知道有沒有更好的寫法0.0
如果要一個一個寫的話, 也許可以!!
但應該是要在程式中判斷是否有子選單才比較好~
如果主選單沒有子選單時要維持sub-menu-wrapper高度為0時則該怎修改?
同上, 當滑鼠移到選單時, 要先判斷是否有子選單。若是贊助會員的話, 下面有範例檔案可直接下載參考。
HI,老師,我加入了會員,但是沒有一直未收到密碼郵件,可以幫我check嗎?謝謝
已幫您變更並寄通知信給您~
您好,請問如果想改成垂直的呈現方式可行嗎?
垂直應該是可行, 但主要要改 CSS 吧!!先試試, 有問題可以一起討論
老師您好,我已改重直方式,但發現滑鼠移到子選單第三項就提早縮回去了,請問要在哪裡做調整呢,謝謝
要看你的程式才知道問題是那邊啦XD