【DEMO】JS实现侧边栏信息展示效果

这次通过中小DEMO,更加深入地了解了

1、使用块模式-立即执行匿名函数,有效地避免了javascript中没有私有作用域而造成的代码污染全局或被覆盖;(function(){})();

2、Javascript事件的冒泡传播机制,使在外部的div上能监听到里面按钮的事件响应

3、修改了事件函数内的this指向回创建对象的两种方法

4、CSS中animation动画属性和keyframes关键帧的transform动画效果,完成了侧边栏内容展示效果的动画效果。

等等

一、使用HTML+CSS实现侧边栏页面布局

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>sidebar demo</title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <link rel="stylesheet" href="sidebar.css">
</head>
<body>
           <div id="sidebar">
               <ul>
                   <li id="me"class="item">
                       <span class="glyphicon glyphicon-user"></span>
                       <div></div>
                   </li>
                   <li id="prof"class="item">
                       <span class="glyphicon glyphicon-usd"></span>
                       <div>资产</div>
                   </li>
                   <li id="asset"class="item">
                       <span class="glyphicon glyphicon-apple"></span>
                       <div>品牌</div>
                   </li>
                   <li id="broadcast"class="item">
                       <span class="glyphicon glyphicon-facetime-video"></span>
                       <div>直播</div>
                   </li>
                   <li id="foot"class="item">
                       <span class="glyphicon glyphicon-eye-open"></span>
                       <div>看过</div>
                   </li>
                   <li id="calendar"class="item">
                       <span class="glyphicon glyphicon-star-empty"></span>
                       <div>日历</div>
                   </li>
               </ul>
               <div id="closeBar">
                      <span class="glyphicon glyphicon-remove"></span>
               </div>
           </div>
           <div class="nav-content" id="me-content"> 
               <div>
                       <div class="nav-con-close">
                           <i class="glyphicon glyphicon-menu-left "></i>
                       </div>
                       <div></div>
               </div>
           </div>           
           <div class="nav-content" id="prof-content"> 
                <div>
                       <div class="nav-con-close">
                          <i class="glyphicon glyphicon-menu-left "></i>
                       </div>
                       <div>资产</div>
                </div>
           </div>
           <div class="nav-content" id="asset-content"> 
                <div>
                        <div class="nav-con-close">
                              <i class="glyphicon glyphicon-menu-left "></i>
                        </div>
                        <div>品牌</div>
                </div>
           </div>
            <div class="nav-content" id="broadcast-content"> 
                 <div>
                          <div class="nav-con-close">
                          <i class="glyphicon glyphicon-menu-left "></i>
                          </div>
                          <div>直播</div>
                 </div>
           </div>
           <div class="nav-content" id="foot-content"> 
                  <div>
                           <div class="nav-con-close">
                           <i class="glyphicon glyphicon-menu-left "></i>
                           </div>
                           <div>看过</div>
                  </div>
           </div>
           <div class="nav-content" id="calendar-content"> 
                  <div>
                            <div class="nav-con-close">
                            <i class="glyphicon glyphicon-menu-left "></i>
                            </div>
                            <div>日历</div>
                  </div>
           </div>
           <script type="text/javascript" src="js/sidebar.js"></script>
    
</body>
</html>
  1. position:fixed;属性

  2. dom结构对代码的实现

closebar作为sidebar element的子元素,在实现动画效果时利用querySelectorAll()方式就可简单实现

实现菜单内容项nav-content时,使它与sidebar平级,都是body的子元素,使用opacity来控制菜单内容项是否显示

ul{
    list-style: none;
    padding-left: 0;
}

#sidebar {
    width: 35px;
    background-color: #e1e1e1;
    padding-top: 200px;
    position: fixed;/*可以使sidebar脱离文档流,使min-height:100%成为一个全屏高度*/
    min-height: 100%;
    z-index: 100;
}

.item {
    font-size: 12px;
    font-family: 'Andale Mono'
    text-align: center;
    margin-top: 5px;
    cursor: pointer;
}

#closeBar{
    position: absolute;
    bottom: 30px;
    width: 35px;
    text-align: center;
    cursor: pointer;
}

.nav-content{
             width: 200px;
             position: fixed;
             min-height: 100%;
             background: #e1e1e1;
             border: 1px solid black;
             z-index: 99;
             opacity: 0;
}

.nav-con-close{
             position: absolute;
             top: 5px;
             right: 5px;
             cursor: pointer;
/*             z-index: 99;*/
}

二、使用Javascript的构造函数创建对象

  1.  使用面向对象的方式:

       根据sidebar对象state属性是opened还是closed,来调用原型链中的相应方法,使代码更加清晰

           Sidebar.prototype.triggerSwitch = function(){
               if(this.state === 'opened'){
                   this.close();
               }else{
                   this.open();
               }
           };

2.在添加事件响应函数的时候,把关闭、打开事件添加在sidebar本身。

(function(){
        var Sidebar = function(eId,closeBarId){
                 this.state = 'opened';
};
        Sidebar.prototype.close = function(){};
        Sidebar.prototype.open = function(){};
)();
/*使用块模式--立即执行的匿名函数*/
(function(){
       //所有声明的变量在构造函数内部,不会向windows添加任何属性
    /*
    构造函数的基本规范:
                 1、构造函数的第一个字母是大写的,与其他函数区分开来
                 2、调用构造函数的时候需要用new,不然会创建全局变量
    */
           var Menubar = function(){
                   this.el = document.querySelector('#sidebar ul'); //菜单项的DOM元素通过css的querySelctor查找得到
                   this.state = 'allClosed';//初始状态时,allClosed,当打开某一个时,则为hasOpened
        this.el.addEventListener('click',function(e){
                   //7.1阻止冒泡事件向上传播,这样点击菜单项,只响应菜单项事件,无关sidebar
                       e.stopPropagation();
         });
        var self = this;
        var currentOpendMenuContent = null;
                  //7.2点击菜单项添加监听事件
        this.menuList = document.querySelectorAll('#sidebar ul > li');
        for( var i=0; i<this.menuList.length;i++){
                                   this.menuList[i].addEventListener('click',function(e){
                         //找到相应的菜单项的内容区域
                         var menuContentEl = document.getElementById(e.currentTarget.id + '-content' );
                 /*
                 7.2-1:没有打开菜单项,打开响应的菜单项
                 7.2-2:有打开的菜单项,关闭该菜单项再打开响应的菜单项
                 */
                        if(self.state === 'allClosed'){
                            console.log( '打开' + menuContentEl.id);
                            /*9.1菜单项打开的动画效果*/
                            //先设置菜单栏的高和左边的位置
                            menuContentEl.style.top = '0px';
                            menuContentEl.style.left = '-85px';
                            menuContentEl.classList.add('menuContent-move-right');
                            self.state = 'hasOpened';
                             self.currentOpendMenuContent = menuContentEl;
                        }else{
                            console.log('关闭' + self.currentOpendMenuContent.id);
                            /*9.2菜单栏关闭的动画效果*/
                            self.currentOpendMenuContent.className = 'nav-content';
                            self.currentOpendMenuContent.style.top = '0';
                            self.currentOpendMenuContent.style.left = '35px';
                            self.currentOpendMenuContent.classList.add('menuContent-move-left')
                            console.log( '打开' + menuContentEl.id);
                            menuContentEl.className = "nav-content"
                               menuContentEl.style.top = '250px';
                               menuContentEl.style.left = '35px';
                               menuContentEl.classList.add('menuContent-move-up');
                            self.state = 'hasOpened';
                               self.currentOpendMenuContent = menuContentEl;
                        }

                      });
        }
        /*10、关闭按钮的样式*/
        this.menuContentList = document.querySelectorAll('.nav-content >div.nav-con-close');
        for(i=0;i<this.menuContentList.length;i++){
            this.menuContentList[i].addEventListener('click', function(e){
                //要关闭菜单内容项,所以要先得到菜单内容项
                            var menuContent = e.currentTarget.parentNode;
                            menuContent.className = "nav-content";
                            menuContent.style.top = '0';
                            menuContent.style.left = '35px';
                            menuContent.classList.add('menuContent-move-left');
                            that.state = 'allClosed';
            });
        }
    };
           /*1、使用构造函数创建sidebar对象 ,
    实例化该对象,向内提供属性eId、closeId*/
           var Sidebar = function(eId,closeBarId){
           /*2、定义对象的状态和属性和方法*/
             this.state = 'opened';          
           /*4、继续完成构造函数
                     4.1、完成对象的初始化,获取所需要的DOM元素
                     4.2、在构造函数的关闭按钮中增加事件响应函数
                              {借助Javascript的事件的冒泡传播机制:使用向上冒泡的机制来传播,在'sidebar的div上能监听closebar按钮的事件响应'}
                     */
                     this.el = document.getElementById(eId || 'sidebar'); //在参数中,需要传入默认的id以防不提供参数
                     this.closeBarEl = document.getElementById(closeBarId || 'closeBar');
                    /*4.3、在el元素上面调用事件函数*/
                    var self = this; 
                    /*
                    修改事件函数内的this指向回Sidebar对象有两种方法:
                          1、修改函数的上下文(比较复杂)
                          2、javascript的特性--闭包
                    this指向构造函数返回的对象,则指向下方 new sidebar返回的对象,
                    闭包原理,再在事件响应函数中调用该变量
                    */
           /*7、在sidebar构造函数中,需要将Menubar函数作为一个属性传进*/
                    this.menubar = new Menubar();
                    this.el.addEventListener("click",function(event){
                               if(event.target !== self.el){
                                   self.triggerSwitch(); //代表打开和关闭的统一函数名称
                               }
                    });

           }; 
           /*3、声明sidebar的两个行为
           对象的行为添加在构造函数的原型链上*/
           Sidebar.prototype.close = function(){
               console.log('关闭sidebar');
           /*8、增加sidebar和关闭按钮的动画效果*/
             this.el.className = 'sidebar-move-left';
             this.closeBarEl.className = 'closeBar-move-right';
               this.state = 'closed';
           };
           Sidebar.prototype.open =  function(){
               console.log('打开sidebar');
           /* 9、增加sidebar打开和关闭按钮向左移动的动画效果*/
             //9.1需要先将sidebar的位置定位到上次关闭的位置
             this.el.style.left ='-120px';
             this.el.className = 'sidebar-move-right';
             this.closeBarEl.style.left = '160px';
             this.closeBarEl.className = 'closeBar-move-left';
               this.state = 'opened';
           };
           /*5、增加triggerSwich()函数*/
           Sidebar.prototype.triggerSwitch = function(){
               if(this.state === 'opened'){
                   this.close();
               }else{
                   this.open();
               }
           };
           /*6、验证构造函数的成果
                    6.1在close函数中console.log输出值来验证
                    6.2增加test单元测试,单元测试一直伴随代码存在*/
           var sidebar = new Sidebar();

})();

三、侧边栏信息展示效果的动画效果的添加

1.使用JavaScript的setInterval,但是这种方法实现的动画不够流畅,实现效果较少,也比较复杂

2.多运动CSS3的动画效果:animations

          scale实现closebar大小的缩放

          rotate实现关闭按钮的旋转

          translateX实现水平方向位移

          translateY实现垂直方向位移

 

/* sidebar向左移动的动画属性 animation样式 */
.sidebar-move-left {
             -webkit-animation-name: sml;
             -moz-animation-name: sml;
             -o-animation-name: sml;
             animation-name: sml;
             -webkit-animation-duration: 1s;
             -moz-animation-duration: 1s;
             -o-animation-duration: 1s;
             animation-duration: 1s;
             -webkit-animation-iteration-count: 1;
             -moz-animation-iteration-count: 1;
             -o-animation-iteration-count: 1;
             animation-iteration-count: 1;
             -webkit-animation-fill-mode: forwards;
             -moz-animation-fill-mode: forwards;
             -o-animation-fill-mode: forwards;
             animation-fill-mode: forwards;
}
/* 关键帧的动画效果 */
@-webkit-keyframes sml{
    from{

        }
    to{
                  -webkit-transform: translateX(-120px);
        }
}
@keyframes sml{
    from{

        }
    to{
                  -webkit-transform: translateX(-120px);
                  transform: translateX(-120px);
        }
}
/* 关闭按钮向右移动的动画属性 */

.closeBar-move-right{
    -webkit-animation-name: sl;
             -moz-animation-name: sl;
             -o-animation-name: sl;
             animation-name: sl;
             -webkit-animation-duration: 1s;
             -moz-animation-duration: 1s;
             -o-animation-duration: 1s;
             animation-duration: 1s;
             -webkit-animation-iteration-count: 1;
             -moz-animation-iteration-count: 1;
             -o-animation-iteration-count: 1;
             animation-iteration-count: 1;
             -webkit-animation-fill-mode: forwards;
             -moz-animation-fill-mode: forwards;
             -o-animation-fill-mode: forwards;
             animation-fill-mode: forwards;
}

@-webkit-keyframes sl{
    from{

    }
    to{
        -webkit-transform: translateX(160px) rotate(405deg) scale(1.5);
    }
}
@keyframes sl{
    from{

    }
    to{
        -webkit-transform: translateX(160px) rotate(405deg) scale(1.5);
        transform: translateX(160px) rotate(405deg) scale(1.5);
    }
}


/* sidebar向右打开的动画效果 */
.sidebar-move-right{
    -webkit-animation-name: smr;
    -moz-animation-name: smr;
    -o-animation-name: smr;
    animation-name: smr;
             -webkit-animation-duration: 1s;
             -moz-animation-duration: 1s;
             -o-animation-duration: 1s;
             animation-duration: 1s;
             -webkit-animation-iteration-count: 1;
             -moz-animation-iteration-count: 1;
             -ms-animation-iteration-count: 1;
             -o-animation-iteration-count: 1;
             animation-iteration-count: 1;
             -webkit-animation-fill-mode: forwards;
             -moz-animation-fill-mode: forwards;
             -ms-animation-fill-mode: forwards;
             -o-animation-fill-mode: forwards;
             animation-fill-mode: forwards;
                    
}
@keyframes smr{
    from{

    }
    to{
                  transform: translateX(120px);
    }
}

.closeBar-move-left {
    -webkit-animation-name: sr;
    -moz-animation-name: sr;
    -o-animation-name: sr;
    animation-name: sr;
    -webkit-animation-duration: 1s;
    -moz-animation-duration: 1s;
    -o-animation-duration: 1s;
    animation-duration: 1s;
    -webkit-animation-iteration-count: 1;
    -moz-animation-iteration-count: 1;
    -o-animation-iteration-count: 1;
    animation-iteration-count: 1;
    -webkit-animation-fill-mode: forwards;
    -moz-animation-fill-mode: forwards;
    -o-animation-fill-mode: forwards;
    animation-fill-mode: forwards;
}
@-webkit-keyframes sr{
    from{
        transform : scale(1.5);
    -webkit-transform : scale(1.5);
    }
    to{
        transform: translateX(-160px)  scale(1)  rotate(-405deg);
    -webkit-transform: translateX(-160px)  scale(1)  rotate(-405deg);
    }
}
@keyframes sr{
    from{
    -webkit-transform : scale(1.5);
        transform : scale(1.5);
    }
    to{
    -webkit-transform: translateX(-160px) scale(1) rotate(-405deg);
                  transform: translateX(-160px) scale(1) rotate(-405deg);
    }
}

.menuContent-move-right {
    -webkit-animation-name: mmr;
    -moz-animation-name: mmr;
    -o-animation-name: mmr;
    animation-name: mmr;
    -webkit-animation-duration: .5s;
    -moz-animation-duration: .5s;
    -o-animation-duration: .5s;
    animation-duration: .5s;
    -webkit-animation-iteration-count: 1;
    -moz-animation-iteration-count: 1;
    -o-animation-iteration-count: 1;
    animation-iteration-count: 1;
    -webkit-animation-fill-mode: forwards;
    -moz-animation-fill-mode: forwards;
    -o-animation-fill-mode: forwards;
    animation-fill-mode: forwards;
}
@keyframes mmr{
    from{
     opacity: 0;
    }
    to{
    opacity: 1;
    transform: translateX(120px);
    }
}

.menuContent-move-left {
    -webkit-animation-name: mml;
    -moz-animation-name: mml;
    -o-animation-name: mml;
    animation-name: mml;
    -webkit-animation-duration: .5s;
    -moz-animation-duration: .5s;
    -o-animation-duration: .5s;
    animation-duration: .5s;
    -webkit-animation-iteration-count: 1;
    -moz-animation-iteration-count: 1;
    -o-animation-iteration-count: 1;
    animation-iteration-count: 1;
    -webkit-animation-fill-mode: forwards;
    -moz-animation-fill-mode: forwards;
    -o-animation-fill-mode: forwards;
    animation-fill-mode: forwards;
}
@-webkit-keyframes mml{
    from{
     opacity: 1;
    }
    to{
    opacity: 0;
    -webkit-transform: translateX(-120px);
    transform: translateX(-120px);
    }
}

@keyframes mml{
    from{
     opacity: 1;
    }
    to{
    opacity: 0;
    transform: translateX(-120px);
    }
}

.menuContent-move-up {
    -webkit-animation-name: mmu;
    -moz-animation-name: mmu;
    -o-animation-name: mmu;
    animation-name: mmu;
    -webkit-animation-duration: .5s;
    -moz-animation-duration: .5s;
    -o-animation-duration: .5s;
    animation-duration: .5s;
    -webkit-animation-iteration-count: 1;
    -moz-animation-iteration-count: 1;
    -o-animation-iteration-count: 1;
    animation-iteration-count: 1;
    -webkit-animation-fill-mode: forwards;
    -moz-animation-fill-mode: forwards;
    -o-animation-fill-mode: forwards;
    animation-fill-mode: forwards;
}
@-webkit-keyframes mmu{
    from{
     opacity: 0;
    }
    to{
    opacity: 1;
    -webkit-transform: translateY(-250px);
    transform: translateY(-250px);
    }
}

@keyframes mmu{
    from{
     opacity: 0;
    }
    to{
    opacity: 1;
    transform: translateY(-250px);
    }
}

 

转载于:https://www.cnblogs.com/siestakc/p/demo.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值