爲何作了這樣一個的功能呢?緣由是前一段時間jQuery羣裏有個朋友想實現這樣一個東東,你們都知道jQuery中有現成的slideDown和slideUp方法,但那是向下展開,而這個是一個徹底相反的效果。css
功能展現連接 http://runjs.cn/detail/v6i9g6g0html
其實這樣一個功能也蠻奇怪的,感受不是很實用,可是當時也沒有一會兒作出來,試着寫了一下子以爲不能立刻寫完就say sorry了。ide
最近呢又開始接着繼續學習jQuery的東西,學到animate動畫的時候,本身就在想,是否是能夠用來實現一下這個功能呢(這個真是個心結啊~~)?而後就試着寫了一下,通過一番波折,不只讓我對animate的使用更加了解以外,也讓我瞭解了一個用jQuery的小技巧,更重要的是,實現這個功能。學習
下面上代碼並作出解析:動畫
Html部分:this
<div> <span>Item1.1</span> <span>Item1.2</span> <span>Item1.3</span> <span>Item1.4</span> </div> <div> <span>Item2.1</span> <span>Item2.2</span> <span>Item2.3</span> <span>Item2.4</span> </div> <div> <span>Item3.1</span> <span>Item3.2</span> </div> <div> <span>Item4.1</span> <span>Item4.2</span> </div> <div class="menu"> <span>Item1</span> <span>Item2</span> <span>Item3</span> <span>Item4</span> </div>
文檔結構是這樣子的,你們能夠看到menu這個主菜單的菜單項的順序與子菜單的實際順序是一致的。這個是爲點擊菜單項上的條目經過位置查找對應子項作的一個設計。spa
jQuery部分:設計
$(function () { $("div").each(function () {//遍歷全部div元素 if ($(this).is("[class='menu']")) {//若是是菜單所在的div $(this).css({ "top": $(this).height() + $(this).position().top, "position": "absolute", "color": "white", "background-color": "white", "width": "500px", "left": "200px" })//爲菜單添加樣式 .children("span").css({ "background-color": "DimGrey", "border": "black solid thin" })//爲菜單項添加樣式 .each(function () {//對每一個菜單項進行遍歷 $(this).click(function () {//添加click事件 var Ind = $("div.menu").children().index(this);//找出當前點擊的菜單項是菜單div中的第幾個span var FocusEle = $("div:eq(" + Ind + ")");//將選中菜單項的子項設成一個變量 if ($("div[class*='up']").size() == 0) {//說明是第一次加載,初次的時候爲沒選中任何菜單項的狀態,因此up的個數爲0 FocusEle.animate( { top: $(this).height() - 10//使對應的子項向上移動 }, 'normal',//中速移動 function () { $(this).addClass("up");//移動完以後爲這個子項加上up的樣式 }); } else {//若是不是初次加載 $("div[class*='up']").animate(//找到正在顯示的菜單子項 { top: $(this).height() + 10//使對應子項向下移動 }, 'normal', function () { $(this).removeClass("up");//移除這個子項的up樣式 FocusEle.animate(//一 { top: $(this).height() - 10//將從新選中的菜單子項向上移動 }, 'normal', function () { $(this).addClass("up");//添加up樣式 }); }) //***************************特別說明********************** // .queue(function () {二 // FocusEle.animate( // { // top: $(this).height() - 10 // }, // 'slow', // function () { // $(this).addClass("up"); // }); // }); } }).css("cursor", "pointer").hover(function () { $(this).css("color", "red"); }, function () { $(this).css("color", "white"); }) }); } else {//若是不是菜單所在的div,即菜單子項 var Index = $("div").index(this); var Left = $("div.menu span:eq(" + Index + ")").position().left + 200;//修改不一樣子項的橫座標,使其與菜單項的條目一致 $(this).css({ "top": $(this).height() + $(this).position().top, "left": Left, "color": "white", "position": "absolute" })//爲菜單子項添加樣式 .children().css({ "background-color": "SlateGrey", "border": "black solid thin", "cursor": "pointer" }).hover(function () { $(this).css("color", "red"); }, function () { $(this).css("color", "white"); }); } }) });
上面的代碼幾乎是逐條註釋的,你們應該都能看懂,主要的實現思想我仍是說一下,你們再結合着註釋看就OK了,你們會發現實現這個功能的時候徹底沒有顯示(show()),隱藏(hide())的操做,最開始我也是一個思惟誤區,覺得必需要用顯示,隱藏去實現,但作着作着發現了一個很是傻的問題,展開的效果實現上是經過移動隱藏和顯示來實現的。怎麼說呢,你們想一想看完電影以後演員名單那部分的東西就能有個概念了。orm
這裏有兩點很重要:htm
一、這5個div所有爲absolute形式的,由於只有這樣才能進行相對移動
二、所謂的消失,其實是4個子項的div被menu div也遮擋住了,因此這裏要知道,我給menu div加了背景色,即白色。
說到這你們應該就知道是如何實現的了吧?
另外在說一 下 註釋中」特別說明」的那部分,其實這部分代碼與它上面不遠處的【一】的代碼是同樣的,只是前面加了.queue這麼東西,這是作什麼的呢?就是將多個動畫放到一個隊列裏,而後依據隊列的次序,一個一個的展示出來。個人初衷就是,若是當前有子項是展開狀態的,那麼就「先」把其關閉,「後」把新點擊的子項展開。
不過不知道爲何,若是是二次進行了點擊的子項,就不會再通過queue 中animate結束時那個function了。這個有明白爲何的朋友能夠幫忙解答一下。然而像我【一】中這個實現,也是合乎規則的。
其實這個小功能還有點弊端,就是若是點擊過快,你們會發現同時展開多項子菜單,緣由是動畫的過程是須要時間的,而在這段時間裏我沒有禁止click事件。應該是用指派命名空間的方法就能夠搞定。你們能夠研究研究而後告訴我。
最後總結了一下,寫這個小功能有點慚愧的說寫了挺長時間,中間換了好多方法爲解決一些問題,如今看來,這麼簡單的東西爲何會寫這麼久,仍是由於最開始的時候沒有想好,邊寫邊想花費了許多時間。之後要改進這種作事方法。
新浪微博:http://weibo.com/zhouhongyu1989 歡迎圍觀~!