目前的网页都右侧边栏,有的是在左侧,类似于导航栏,如一些购物商城,还有一些是在网页的右下角,一般是提示客服信息和微信/QQ等服务。
这里都涉及到一个动画效果的展示,即点击侧边栏时会在侧边栏的右侧或者左侧出现相应的信息。如下图慕课网右下角的侧边栏,把鼠标放在最后一个微信图标上,会弹出慕课网的二维码。
实现动画效果的方式有两种,一种是JavaScript setInterval函数,即设置定时器,实现简单,但是效果不佳。动画效果不够平滑,而且实现的效果有限,不能实现旋转和3D变换。用户体验有待提高。另一种是使用CSS3来实现动画效果。
css属性
描述动画的运行属性(运行时间、次数等)
transition (过渡)
animations( 动画)
描述动画的执行属性(参与动画的属性,效果等)
transform (变形)——translate
代码实现:
sidebar.html
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>sideBar demotitle>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="bootstrap/dist/css/bootstrap.css">
<link rel="stylesheet" href="bootstrap/dist/css/bootstrap-theme.css">
head>
<body>
<div id = "sidebar">
<ul>
<li id="prof" class="item">
<span class="glyphicon glyphicon-user">span>
<div>我div>
li>
<li id="asset" class="item">
<span class="glyphicon glyphicon-user">span>
<div>资产div>
li>
<li id="brand" class="item">
<span class="glyphicon glyphicon-user">span>
<div>商品div>
li>
<li id="foot" class="item">
<span class="glyphicon glyphicon-user">span>
<div>足迹div>
li>
<li id="calender" class="item">
<span class="glyphicon glyphicon-user">span>
<div>日历div>
li>
ul>
<div id="closeBar">
<span class="glyphicon glyphicon-remove">span>
div>
div>
<div class="nav-content" id="prof-content">
<div class="nav-con-close">
<span class="glyphicon glyphicon-chevron-left">span>
div>
<div>我div>
div>
<div class="nav-content" id="asset-content">
<div class="nav-con-close">
<span class="glyphicon glyphicon-chevron-left">span>
div>
<div>资产div>
div>
<div class="nav-content" id="brand-content">
<div class="nav-con-close">
<span class="glyphicon glyphicon-chevron-left">span>
div>
<div>商标div>
div>
<div class="nav-content" id="foot-content">
<div class="nav-con-close">
<span class="glyphicon glyphicon-chevron-left">span>
div>
<div>足迹div>
div>
<div class="nav-content" id="calender-content">
<div class="nav-con-close">
<span class="glyphicon glyphicon-chevron-left">span>
div>
<div>日历div>
div>
<script src="sideBar.js">script>
body>
html>
注:
style.css
ul{ list-style: none; padding-left: 0; } #sidebar{ width: 35px; background-color: #e1e1e1; padding-top: 200px; /*设置高度100%都是相对父元素的100%,fixed使该元素脱离流,相对屏幕的100%,即全屏*/ position: fixed; min-height:100%; z-index: 100; } .item{ font-size: 12px; font-family: 'Microsoft New Tai Lue'; text-align: center; margin-top: 5px; } #closeBar{ position: absolute; bottom: 30px; width: 35px; text-align: center; /*提示别人是个按钮 手的样式*/ cursor: pointer; } .nav-content{ width: 200px; position: fixed; min-height: 100%; background-color: #e1e1e1; /*调试代码时经常使用border,帮我们定位到div的一个区域*/ border: 1px solid black; z-index: 99; /*使用透明度为0来隐藏元素*/ opacity: 0; } .nav-con-close{ position: absolute; top: 5px; right: 5px; cursor: pointer; } .sidebar-move-left{ -webkit-animation:sml; -o-animation:sml; animation: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; /*执行方向,动画执行结束时保持在它结束时的状态*/ animation-fill-mode: forwards; -moz-animation-fill-mode: forwards; -o-animation-fill-mode: forwards; -webkit-animation-fill-mode: forwards; } @keyframes sml { from{ } to{ transform: translateX(-120px); } } .closebar-move-right{ -webkit-animation:cmr; -o-animation:cmr; animation:cmr; /*持续时间*/ -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; /*执行方向,动画执行结束时保持在它结束时的状态*/ animation-fill-mode: forwards; -moz-animation-fill-mode: forwards; -o-animation-fill-mode: forwards; -webkit-animation-fill-mode: forwards; } @keyframes cmr { from{ } to{ transform: translateX(160px) rotate(405deg) scale(1.5); } } .sidebar-move-right{ -webkit-animation:smr; -o-animation:smr; animation: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; -o-animation-iteration-count: 1; animation-iteration-count: 1; /*执行方向,动画执行结束时保持在它结束时的状态*/ animation-fill-mode: forwards; -moz-animation-fill-mode: forwards; -o-animation-fill-mode: forwards; -webkit-animation-fill-mode: forwards; } @keyframes smr { from{ } to{ transform: translateX(120px); } } .closebar-move-left{ -webkit-animation:cml; -moz-animation-name: cml; -o-animation:cml; animation:cml; /*持续时间*/ -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; /*执行方向,动画执行结束时保持在它结束时的状态*/ animation-fill-mode: forwards; -moz-animation-fill-mode: forwards; -o-animation-fill-mode: forwards; -webkit-animation-fill-mode: forwards; } @keyframes cml { from{ transform: scale(1.5); } to{ transform:translateX(-160px) rotate(-405deg) scale(1); } } .menuContent-move-right{ -webkit-animation:mmr; -moz-animation-name: mmr; -o-animation:mmr; animation: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; /*执行方向,动画执行结束时保持在它结束时的状态*/ animation-fill-mode: forwards; -moz-animation-fill-mode: forwards; -o-animation-fill-mode: forwards; -webkit-animation-fill-mode: forwards; } @keyframes mmr { from{ opacity: 0; } to{ opacity: 1; transform:translateX(120px); } } .menuContent-move-left{ -webkit-animation:mml; -moz-animation-name: mml; -o-animation:mml; animation:mml; /*持续时间*/ -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; /*执行方向,动画执行结束时保持在它结束时的状态*/ animation-fill-mode: forwards; -moz-animation-fill-mode: forwards; -o-animation-fill-mode: forwards; -webkit-animation-fill-mode: forwards; } @keyframes mml { from{ opacity: 1; } to{ opacity: 0; transform:translateX(-120px); } } .menuContent-move-up{ -webkit-animation:mmu; -moz-animation-name: mmu; -o-animation:mmu; animation:mmu; /*持续时间*/ -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; /*执行方向,动画执行结束时保持在它结束时的状态*/ animation-fill-mode: forwards; -moz-animation-fill-mode: forwards; -o-animation-fill-mode: forwards; -webkit-animation-fill-mode: forwards; } @keyframes mmu { from{ opacity: 0; } to{ opacity: 1; transform:translateY(-250px); } }
sidebar.js
/* var sideBar = {} 会造成全局污染,sideBar赋给Windows,作为windows的一个属性*/ /*目前常用模块模式的方法,避免全局污染*/ /*立即执行函数*/ (function () { var MenuBar = function () { this.el = document.querySelector('#sidebar ul'); this.state = 'allClosed'; /*禁止向上传播,不然点击sidebar中的ul也会触发和点击关闭按钮一样的事件*/ this.el.addEventListener('click',function (e) { e.stopPropagation(); }); var self = this; this.menulist = document.querySelectorAll('#sidebar ul > li'); this.currentOpenMenuContent = null; for(var i = 0;i<this.menulist.length;i++){ this.menulist[i].addEventListener('click',function (e) { var menuContentEl = document.getElementById(e.currentTarget.id +'-content'); if(self.state === 'allClosed'){ console.log('open'+menuContentEl.id); menuContentEl.style.top = '0'; menuContentEl.style.left = '-85px'; menuContentEl.className = 'nav-content'; menuContentEl.classList.add('menuContent-move-right'); self.state='hasOpened'; self.currentOpenMenuContent = menuContentEl; }else{ console.log('closed'+self.currentOpenMenuContent.id); console.log('open'+menuContentEl.id); self.currentOpenMenuContent.className = 'nav-content'; self.currentOpenMenuContent.style.top = '0'; self.currentOpenMenuContent.style.left = '35px'; self.currentOpenMenuContent.classList.add('menuContent-move-left'); menuContentEl.className='nav-content'; menuContentEl.style.top = '250px'; menuContentEl.style.left = '35px'; menuContentEl.classList.add('menuContent-move-up'); self.state='hasOpened'; self.currentOpenMenuContent = menuContentEl; } }); } this.menuContentList = document.querySelectorAll('.nav-content > div.nav-con-close'); for(var 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'); this.state='allClosed'; }); } }; /*Sidebar第一个字母大写,构造函数的基本规范 */ var Sidebar = function (eId,closeBarId) { this.state = 'opened'; this.el = document.getElementById(eId || 'sidebar'); this.closeBarEl = document.getElementById(closeBarId || 'closeBar'); /*默认向上冒泡,第三个参数可以不写*/ var self = this; this.menubar = new MenuBar(); this.el.addEventListener('click',function (event) { if(event.target !== self.el){ //console.log(this); self.triggerSwich(); } }); } Sidebar.prototype.close = function () { console.log('关闭sidebar'); this.el.className = 'sidebar-move-left'; this.closeBarEl.className = 'closebar-move-right'; this.state = 'closed'; }; Sidebar.prototype.open = function () { console.log('打开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'; }; Sidebar.prototype.triggerSwich = function () { if(this.state === 'opened'){ this.close(); }else{ this.open(); } }; var sidebar = new Sidebar(); })();