案例:筋斗云案例
实现功能:
① 鼠标经过某个小li,筋斗云跟着到当前小li的位置
② 鼠标离开这个小li,筋斗云就复原为原来的位置
③ 鼠标点击了某个小li,筋斗云就会留在点击这个小li的位置
具体实现思路如下:
- 利用动画函数做该动画效果
- 原先的筋斗云的起始位置是0
- 鼠标经过某个小li,就把当前小li的offsetLeft位置作为目标值即可
- 鼠标离开某个小li,就把目标值设为0
<!-- CSS样式 --> <style> * { margin: 0; padding: 0 } ul { list-style: none; } body { background-color: black; } .c-nav { width: 900px; height: 42px; background: #fff url(images/rss.png) no-repeat right center; margin: 100px auto; border-radius: 5px; position: relative; } .c-nav ul { position: absolute; } .c-nav li { float: left; width: 83px; text-align: center; line-height: 42px; } .c-nav li a { color: #333; text-decoration: none; display: inline-block; height: 42px; } .c-nav li a:hover { color: white; } .cloud { position: absolute; left: 0; top: 0; width: 83px; height: 42px; background: url(images/cloud.gif) no-repeat; } </style>
<!-- 页面布局 --> <body> <div id="c_nav" class="c-nav"> <span class="cloud"></span> <ul> <li><a href="#">首页新闻</a></li> <li><a href="#">师资力量</a></li> <li><a href="#">活动策划</a></li> <li><a href="#">企业文化</a></li> <li><a href="#">招聘信息</a></li> <li><a href="#">公司简介</a></li> <li><a href="#">我是佩奇</a></li> <li><a href="#">啥是佩奇</a></li> </ul> </div> </body>
封装的动画函数animate.js文件:
function animate(obj, target, callback) { // console.log(callback); callback = function() {} 调用的时候 callback() // 先清除以前的定时器,只保留当前的一个定时器执行 clearInterval(obj.timer); obj.timer = setInterval(function() { // 步长值写到定时器的里面 // 把我们步长值改为整数 不要出现小数的问题 // var step = Math.ceil((target - obj.offsetLeft) / 10); var step = (target - obj.offsetLeft) / 10; step = step > 0 ? Math.ceil(step) : Math.floor(step); if (obj.offsetLeft == target) { // 停止动画 本质是停止定时器 clearInterval(obj.timer); // 回调函数写到定时器结束里面 // if (callback) { // // 调用函数 // callback(); // } // 注意此处的优化代码 callback && callback(); } // 把每次加1 这个步长值改为一个慢慢变小的值 步长公式:(目标值 - 现在的位置) / 10 obj.style.left = obj.offsetLeft + step + 'px'; }, 15); }
<!-- 引入动画文件 --> <script src="animate.js"></script> <!-- JS逻辑代码 --> <script> window.addEventListener('load', function() { // 1. 获取元素 var cloud = document.querySelector('.cloud'); var c_nav = document.querySelector('.c-nav'); var lis = c_nav.querySelectorAll('li'); // 2. 给所有的小li绑定事件 // 这个current 做为筋斗云的起始位置 var current = 0; for (var i = 0; i < lis.length; i++) { // (1) 鼠标经过把当前小li 的位置做为目标值 lis[i].addEventListener('mouseenter', function() { animate(cloud, this.offsetLeft); }); // (2) 鼠标离开就回到起始的位置 lis[i].addEventListener('mouseleave', function() { animate(cloud, current); }); // (3) 当我们鼠标点击,就把当前位置做为目标值 lis[i].addEventListener('click', function() { current = this.offsetLeft; }); } }) </script>