- 我们知道,CSS3的transition过渡属性可以实现动画。
- JavaScript可以利用CSS3的transition属性轻松实现元素动画。
- JS和CSS3结合实现动画规避了定时器制作动画的缺点。
函数节流
- 函数节流:一个函数执行一次后,只有大于设定的执行周期后才允许执行第二次。
- 函数节流非常容易实现,只需要借助setTimeout()延时器。
var lock = true; function 需要节流的函数() { // 如果锁是关闭状态,则不执行 if (!lock) return; // 函数核心语句 // 关锁 lock = false; // 指定毫秒数后将锁打开 setTimeout(function() { lock = true; }, 2000); }
示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> #box { position: absolute; top: 100px; left: 100px; width: 100px; height: 100px; background-color: orange; } </style> </head> <body> <button id="btn">开始运动</button> <div id="box"></div> <script> // 得到元素 var btn = document.getElementById('btn'); var box = document.getElementById('box'); // 标识量,指示当前盒子在左边还是右边 var pos = 1; // 1左边,2右边 // 函数节流 // 添加锁 var lock = true; // 按钮监听 btn.onclick = function() { // 首先检查锁是否是关闭 if (!lock) return; // 把过渡加上 box.style.transition = 'all .5s linear 0s'; if (pos == 1) { // 瞬间移动,但是由于有过渡,所以是动画 box.style.left = '500px'; pos = 2; } else if (pos == 2) { // 瞬间移动,但是由于有过渡,所以是动画 box.style.left = '100px'; pos = 1; } // 关锁 lock = false; // 设置延时器开锁,时间与过渡时间最好相同 setTimeout(function() { lock = true; }, 500) }; </script> </body> </html>
动画效果开发1 - 无缝连续滚动特效
- 首先将页面上图片复制一倍在后面,然后依次滚动。
- 当赋值的后半段火车的0号头贴到了盒子的左边框的时候,那么就瞬间移动到原点,重新执行动画。
- 最后再将盒子外面的部分隐藏即可。
完整代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { margin: 0; padding: 0; } .box { margin: 50px auto; width: 840px; height: 130px; border: 10px solid #999; overflow: hidden; } ul { list-style: none; width: 5000px; position: relative; } li { float: left; margin-right: 10px; } </style> </head> <body> <div id="box" class="box"> <ul id="list"> <li><img src="image/number/0.png" alt=""></li> <li><img src="image/number/1.png" alt=""></li> <li><img src="image/number/2.png" alt=""></li> <li><img src="image/number/3.png" alt=""></li> <li><img src="image/number/4.png" alt=""></li> <li><img src="image/number/5.png" alt=""></li> </ul> </div> <script> var box = document.getElementById('box'); var list = document.getElementById('list'); // 复制多一遍所有的li list.innerHTML += list.innerHTML; // 全局变量,表示当前list的left值 var left = 0; // 定时器,全局变量 var timer; // move(); // 动画封装成函数 function move() { // 设表先关,防止动画积累 clearInterval(timer); timer = setInterval(function() { left -= 4; // 验收 if (left <= -1260) { left = 0; } list.style.left = left + 'px'; }, 20); } // 鼠标进入停止定时器 box.onmouseenter = function() { clearInterval(timer); }; // 鼠标离开继续定时器 box.onmouseleave = function() { move(); }; </script> </body> </html>
动画效果开发2 - 跑马灯轮播图特效
- 首先需要克隆第一个图,并添加到列表最后。
- 右按钮临界点(第五张图),需要先正常过渡到克隆的第一张图上(第六张图),在过渡完成时,瞬间用原始的第一张图(第一张图)去替换掉克隆的第一张图(第六张图)。
- 左按钮临界点(第一张图),需要先瞬间用克隆的第一张图(第六张图)去替换掉原始的第一张图(第一张图),然后再正常过渡到第五张图即可。
- 其他的图正常过渡,最后设置隐藏即可。
完整代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { margin: 0; padding: 0; } .carousel { margin: 50px auto; width: 650px; height: 360px; border: 1px solid #000; position: relative; overflow: hidden; } .carousel ul { list-style: none; width: 5000px; position: relative; left: 0; transition: left .5s ease 0s; } .carousel ul li { float: left; width: 650px; height: 360px; } .carousel a { position: absolute; top: 50%; margin-top: -25px; width: 50px; height: 50px; background-color: rgb(28, 180, 226); border-radius: 50%; } .carousel a.leftbtn { left: 20px; } .carousel a.rightbtn { right: 20px; } </style> </head> <body> <div class="carousel"> <ul id="list"> <li><img src="image/0.jpg" alt=""></li> <li><img src="image/1.jpg" alt=""></li> <li><img src="image/2.jpg" alt=""></li> <li><img src="image/3.jpg" alt=""></li> <li><img src="image/4.jpg" alt=""></li> </ul> <a href="javascript:;" class="leftbtn" id="leftbtn"></a> <a href="javascript:;" class="rightbtn" id="rightbtn"></a> </div> <script> // 得到按钮和ul,ul整体进行运动 var list = document.getElementById('list'); var leftbtn = document.getElementById('leftbtn'); var rightbtn = document.getElementById('rightbtn'); // 克隆第一张图片 // 要设置true使用深克隆 var cloneli = list.firstElementChild.cloneNode(true); list.appendChild(cloneli); // 当前ul显示到第几张了,从0开始数 var idx = 0; // 节流锁 var lock = true; // 右边按钮监听 rightbtn.onclick = function() { // 判断锁的状态 if (!lock) return; // 给list加过渡,为什么要加??css中不是已经加了么?? // 这是因为最后一张图片会把过渡去掉 list.style.transition = 'left .5s ease 0s'; idx--; if (idx < -4) { // 设置一个延时器,延时器的目的就是让过渡动画结束之后,将ul瞬间拉回0的位置 setTimeout(function() { // 取消掉过渡,因为要的是瞬间移动,不是“咕噜”回去 list.style.transition = 'none'; list.style.left = 0; idx = 0; }, 500); } list.style.left = idx * 650 + 'px'; lock = false; // 函数节流 setTimeout(function() { lock = true; }, 500); } // 左边按钮监听 leftbtn.onclick = function() { // 判断锁的状态 if (!lock) return; lock = false; // 判断是不是第0张,如果是,就要瞬间用假的替换真的 if (idx == 0) { // 取消掉过渡,因为要的是瞬间移动,不是“咕噜”过去 list.style.transition = 'none'; // 直接瞬间移动到最后的假图片上 list.style.left = -5 * 650 + 'px'; // 设置一个延时器,这个延时器的延时时间可以是0毫秒,虽然是0毫秒,但是可以让我们过渡先是瞬间取消,然后再加上 setTimeout(function() { // 加过渡 list.style.transition = 'left .5s ease 0s'; // idx改为真正的最后一张 idx = -4; list.style.left = idx * 650 + 'px'; }, 0) } else { idx++; list.style.left = idx * 650 + 'px'; } // 函数节流 setTimeout(function() { lock = true; }, 500); } </script> </body> </html>
动画效果开发3 - 呼吸轮播图特效
- 需要注意的是点击按钮切换时,先将老图淡出,再将新图淡入即可。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { margin: 0; padding: 0; } .carousel { margin: 50px auto; width: 650px; height: 360px; border: 1px solid #000; position: relative; } .carousel ul { list-style: none; } .carousel ul li { position: absolute; top: 0; left: 0; /* 透明度都是0 */ opacity: 0; transition: opacity 1s ease 0s; } /* 只有第一张透明度是1 */ .carousel ul li:first-child { opacity: 1; } .carousel a { position: absolute; top: 50%; margin-top: -25px; width: 50px; height: 50px; background-color: rgb(28, 180, 226); border-radius: 50%; } .carousel a.leftbtn { left: 20px; } .carousel a.rightbtn { right: 20px; } </style> </head> <body> <div class="carousel"> <ul id="list"> <li><img src="image/0.jpg" alt=""></li> <li><img src="image/1.jpg" alt=""></li> <li><img src="image/2.jpg" alt=""></li> <li><img src="image/3.jpg" alt=""></li> <li><img src="image/4.jpg" alt=""></li> </ul> <a href="javascript:;" class="leftbtn" id="leftbtn"></a> <a href="javascript:;" class="rightbtn" id="rightbtn"></a> </div> <script> // 得到按钮和ul,ul整体进行运动 var list = document.getElementById('list'); var leftbtn = document.getElementById('leftbtn'); var rightbtn = document.getElementById('rightbtn'); var lis = list.getElementsByTagName('li'); // 当前是第几张图显示 var idx = 0; // 节流锁 var lock = true; // 右边按钮监听 rightbtn.onclick = function() { // 判断锁的状态 if (!lock) return; lock = false; // 还没有改idx,此时的idx这个图片就是老图,老图淡出 lis[idx].style.opacity = 0; idx++; if (idx > 4) idx = 0; // 改了idx,此时的idx这个图片就是新图,新图淡入 lis[idx].style.opacity = 1; // 动画结束之后,开锁 setTimeout(function() { lock = true; }, 500); } // 左边按钮监听 leftbtn.onclick = function() { // 判断锁的状态 if (!lock) return; lock = false; // 还没有改idx,此时的idx这个图片就是老图,老图淡出 lis[idx].style.opacity = 0; idx--; if (idx < 0) idx = 4; // 改了idx,此时的idx这个图片就是新图,新图淡入 lis[idx].style.opacity = 1; // 动画结束之后,开锁 setTimeout(function() { lock = true; }, 500); } </script> </body> </html>