jQuery實現帶展開動畫的導航欄效果

設計和自定義一個帶展開動畫效果的導航欄,嘗試寫瞭一個demo,加上設計和調試差不多寫瞭一天吧。
這裡就來講講如何從設計->寫佈局->寫樣式->寫JS代碼 完成一個完全自己設計的導航欄。

HTML寫佈局,CSS寫樣式,JS寫動畫效果和事件響應等,考慮到JQuery對DOM操作的便利性,這裡選擇用JQuery可以達到事半功倍的效果。

設計:

如果覺得自己下載的一些導航欄插件太千篇一律瞭,那麼就設計一個自己喜歡的導航欄。可以先拿張紙畫畫自己希望要一個什麼樣的導航最終想要達到什麼樣的效果。
比如這裡想要寫一個導航欄,鼠標懸浮在每一章節上面,可以橫向伸展出下面的每一個節點,節點的出現有一個跳躍的動作。

寫佈局:

在理清楚思路以後,開始寫HTML,這步相對比較簡單。 一般用到<div> <span> <a> 這幾個標簽就可以瞭。寫清楚層次關系是很重要的,這裡

要說明幾點:

<div> 是一個塊級元素。這意味著它的內容自動地開始一個新行。
<span>標簽不會獨自占一行,一般用來包裹內容。因為不是塊級元素設置width、height屬性無效
<a>標簽當然是用來放鏈接的啦

寫樣式:

樣式需要慢慢的調試,要用耐心。配色可以參考一些經典的配色方案。因為我們想要實現橫向伸展出下面的每一個節點,必定會需要類似於多欄佈局那樣的效果,<span> 和<div>標簽設置樣式 display:inline-block可以將對象呈遞為內聯對象,但是對象的內容作為塊對象呈遞。簡單的說就是既一個設置width、height又不會強制占據一行。也可以用 display:flex這個牛逼的CSS3佈局屬性,實現多欄多列佈局。

寫JS:

佈局寫好之後就需要實現功能瞭。前面提到導航欄實現鼠標懸浮在每一章節上面,可以橫向伸展出下面的每一個節點。自然會用到hover事件,來看看jQuery的hover事件。

$(selector).hover(inFunction,outFunction)

括號內第一個function必需寫,規定 mouseover 事件發生時運行的函數。
第二個function可選,規定 mouseout 事件發生時運行的函數。

jQuery同樣可以方便的實現動畫效果, animate() 方法通過CSS樣式將元素從一個狀態改變為另一個狀態。
CSS屬性值是逐漸改變的,這樣就可以創建動畫效果,這裡不再贅述。

因為想要節點按順序依次出現,但又不想用animate的排隊,所以我寫瞭一個 回調函數,在回調函數中寫瞭setTimeout延時,用addClass給響應的節點加上animation動畫樣式。

代碼:

<!--Created by CC on 2017/10/14-->
 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>~myNav~</title>
    <script type="text/javascript" src="jquery.js"></script>
    <!--樣式-->
    <style type="text/css">
 
        .triangle-right {
            width: 0;
            height: 0;
            border-left: 20px solid #FF7800;
            border-bottom: 20px solid transparent;
            border-top:2px dotted #333333;
            display: inline-block;
            margin-top:10px;
            vertical-align: top;
        }
        .mynav
        {
            font-family: punctuation,"PingFangSC-Regular","Microsoft Yahei","sans-serif";
            -webkit-font-smoothing: subpixel-antialiased;
            margin:10px 2%;
            width:90%;
            heigth:450px;
            display:flex;
        }
        .nav-left{
             flex:auto;
            heigth:200px;
            font-size:20px;
            font-weight: 700;
            text-align: center;
            background-color:#505050 ;
            color:#FF7800;
            border-right:3px solid #FF7800;
            width:80px;
            padding-top:40px;
        }
        .nav-right{
             flex:auto;
             width:90%
        }
        .nav-right div{
            position:relative;
        }
        .cap{
            display:inline-block;
            width:70px;
            height:30px;
            background-color: #FF7800;
            margin:10px 0;
            border-bottom:2px dotted #333333;
            border-top:2px dotted #333333;
        }
 
        .child{
            display:inline-block;
            width:0px;
            border-top:2px dotted #333333;
            vertical-align: top;
            margin-top: 10px;
        }
        span.cap-child
        {
            position:absolute;
            border:2px solid #333333;
            background-color: #505050;
            color: #ffffff;
            -webkit-border-radius: 8px;
            -moz-border-radius: 8px;
            border-radius: 8px;
            /*top:5px;*/
            left:0px;
 
        }
        span.cap-child a{
            font-size:15px;
            color:white;
        }
        span.cap-child a:hover{
            color: #ffc8aa;
        }
        .hr-over{
            position:absolute;
            -webkit-border-radius: 10px;
            -moz-border-radius: 10px;
            border-radius: 10px;
            background-color: #FF7800;
            width:20px;
            height:20px;
            margin-top:-10px;
            border:1px solid #333333;
        }
        .showit{
            animation: cho-show .5s;
        }
        @keyframes cho-show {
            0% {
                -webkit-transform-origin: right bottom;
                transform-origin: right bottom;
                -webkit-transform: rotate3d(0, 0, 1, 45deg);
                transform: rotate3d(0, 0, 1, 45deg);
                opacity:0;
            }
            100% {
                -webkit-transform-origin: right bottom;
                transform-origin: right bottom;
                -webkit-transform: none;
                transform: none;
                opacity:1;
            }
        }
 
    </style>
</head>
<body>
<!--佈局-->
<div class="mynav">
    <div class="nav-left">
        目<br/>錄<br>
        <span style="font-size:6px">
            by cc
        </span>
    </div>
    <div class="nav-right" >
        <div >
            <span class="cap ">Chapter1</span><div class="triangle-right"></div>
            <div class="child">
            </div>
        </div>
        <div >
            <span class="cap">Chapter2</span><div class="triangle-right"></div>
            <div class="child">
            </div>
        </div>
        <div >
            <span class="cap">Chapter3</span><div class="triangle-right"></div>
            <div class="child">
            </div>
        </div>
    </div>
</div>
 
<script type="text/javascript">
    var active='';
    var space=80;
    var myNodes =[{ name:'Chapter1',
                    children: [{name:'字符集',url:'https://baike.baidu.com/item/%E5%AD%97%E7%AC%A6%E9%9B%86/946585?fr=aladdin'},
                    {name:'註釋',url:'cc/sd1/index'},
                    {name:'直接量',url:'cc/sd2/index'}
        ]},
        {name:'Chapter2',
        children:[{name:'數字',url:'#'},
        {name:'文本',url:'#'},
        {name:'佈爾值',url:'#'},
        {name:'全局對象',url:'#'},
        {name:'包裝對象',url:'#'}
        ]},
        {
            name:'Chapter3',
            children: [{name:'貓貓',url:'#'},
            {name:'狗狗',url:'#'}
        ]}
    ];
 
    $('.cap').hover(function(){
        var cap=this;
        var mybox=$(cap.parentNode).find('.child');
        if(active!=this.innerHTML)
        {
            //變色
            $(cap).css('background-color','#ffc8aa');
            $(cap).next().css('border-left-color','#ffc8aa');
            //清理原來的內容
           for(var j=0;j<$('.child').length;j++)
            {
                //console.log($('.child')[j]);
                $($('.child')[j]).empty();
                $($('.child')[j]).css('width','0px');
            }
 
            active=this.innerHTML;
            myNodes.forEach(function(item){
                    if(active==item.name)
                    {
                        myAnimate(item.children,mybox);
 
                    }
                }
            );
        }
         //順序顯示
        orderShow($(mybox),$(mybox).children().length-1);
 
    }, function(){
        //變色
        $(this).css('background-color','#FF7800');
        $(this).next().css('border-left-color','#FF7800');
 
    });
 
 
    function myAnimate(arr,ele)
    {
       // console.log(ele);
        var $ele=$(ele);
        var pos;
        arr.forEach(function(item,index){
            pos=space*index+20;
            addOne(item,pos+'px');
        });
        $ele.animate({width:pos+100+'px'},200,'linear',function(){
            var left=pos+80+'px';
            $ele.append("<span class='hr-over' style='left:"+left+"'></span>");
        });
        function addOne(item,pos)
        {
            var mylink="<a href='"+item.url+"'>"+item.name+"</a>";
            $ele.append("<span class='cap-child' style='display:none;left:"+pos+"'>"+mylink+"</span>")
        }
    }
 
    function orderShow($it,times)
    {
        if(times>=0)
        {
            setTimeout(function(){
                $($it.children()[times]).css('display','block')
                $($it.children()[times]).addClass('showit');
            orderShow($it,times-1)
        },100);
        }
        else
            return;
 
    }
</script>
 
</body>
</html>

效果:

動態效果:

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: