一、定时器
1. setInterval()
函数
-
setInterval()
函数可以重复调用一个函数,在每次调用之间具有固定的时间间隔
。setInterval(function () { // 这个函数将自动被以固定间隔时间调用 }, 2000);
- 第一个参数是函数
- 第二个参数是间隔时间,以毫秒为单位,1000毫秒是1秒
-
函数的参数
setInterval()
函数可以接收第3、4……个参数,它们将按顺序传入函数setInterval(function (a, b) { // 形式参数a的值是88,形式参数b的值是66 }, 2000, 88, 66);
- 从第三个参数开始,表示传入函数内的参数
-
具名函数也可以传入setInterval
var a = 0; function fun() { console.log(++a); } setInterval(fun, 1000);
- 具名函数当做第一个参数,注意这里没有圆括号!
-
清除定时器
clearInterval()
函数可以清除一个定时器。// 设置定时器,并且用timer变量接收这个定时器 var timer = setInterval(function () { }, 2000); // 点击按钮时,清除定时器 oBtn.onclick = function () { clearInterval(timer); }
- 用变量
timer
- 清除定时器的时候,要传入定时器变量
- 用变量
二、延时器
1. setTimeout()
函数
setTimeout()
函数可以设置一个延时器,当指定时间到了之后,会执行函数一次,不再重复执行。setTimeout(function () { // 这个函数会在2秒后执行一次 }, 2000);
- 清除延时器
clearTimeout()
函数可以清除延时器,和clearInterval()
非常类似
三、异步语句
-
setInterval()
和setTimeout()
是两个异步语句。 -
异步(asynchronous):不会阻塞CPU继续执行其他语句,当异步完成时,会执行"回调函数"(callback)
setTimeout(function () { console.log('A'); }, 2000); console.log('B');
- 打印:B A
console.log('B');
异步语句不会阻塞程序的正常执行。
-
使用定时器实现动画
<!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'); // 全局变量盒子的left值 var left = 100; // 按钮监听 btn.onclick = function () { var timer = setInterval(function () { // 改变全局变量 left += 10; if (left >= 1000) { clearInterval(timer); } // 设置left属性 box.style.left = left + 'px'; }, 20); }; </script> </body> </html>
- 使用定时器可以实现动画,利用的就是"视觉暂留"原理。
- 使用定时器实现动画较为不便:
- 不方便根据动画总时间计算步长
- 运动方向要设置正负
- 多种运动进行叠加较为困难(比如一个方形一边移动 一边变为圆形)
-
JS和CSS3结合实现动画
- JavaScript可以利用
CSS3
的transition
属性轻松实现元素动画。 - JS和CSS3结合实现动画规避了定时器制作动画的缺点
- JavaScript可以利用
-
函数节流
- 函数节流:一个函数执行一次后,只有大于设定的执行周期 后才允许执行第二次
- 函数节流非常容易实现,只需要借助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> * { margin: 0; padding: 0; } .box { width: 1000px; height: 130px; border: 1px solid #000; margin: 50px auto; overflow: hidden; } .box ul { list-style: none; /* 设置大一点,这样li才能浮动 */ width: 5000px; position: relative; } .box ul li { float: left; margin-right: 10px; } </style> </head> <body> <div id="box" class="box"> <ul id="list"> <li><img src="images/number/0.png" alt=""></li> <li><img src="images/number/1.png" alt=""></li> <li><img src="images/number/2.png" alt=""></li> <li><img src="images/number/3.png" alt=""></li> <li><img src="images/number/4.png" alt=""></li> <li><img src="images/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>
-
跑马灯轮播图
<!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 { width: 650px; height: 360px; border: 1px solid #000; margin: 50px auto; position: relative; overflow: hidden; } .carousel ul { list-style: none; width: 6000px; position: relative; left: 0px; transition: left .5s ease 0s; } .carousel ul li { float: left; } .carousel .leftbtn { position: absolute; left: 20px; top: 50%; margin-top: -25px; width: 50px; height: 50px; background-color: rgb(28, 180, 226); border-radius: 50%; } .carousel .rightbtn { position: absolute; right: 20px; top: 50%; margin-top: -25px; width: 50px; height: 50px; background-color: rgb(28, 180, 226); border-radius: 50%; } </style> </head> <body> <div class="carousel"> <ul id="list"> <li><img src="images/beijing/0.jpg" alt=""></li> <li><img src="images/beijing/1.jpg" alt=""></li> <li><img src="images/beijing/2.jpg" alt=""></li> <li><img src="images/beijing/3.jpg" alt=""></li> <li><img src="images/beijing/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 leftbtn = document.getElementById('leftbtn'); var rightbtn = document.getElementById('rightbtn'); var list = document.getElementById('list'); // 克隆第一张图片 var cloneli = list.firstElementChild.cloneNode(true); list.appendChild(cloneli); // 当前ul显示到第几张了,从0开始数 var idx = 0; // 节流锁 var lock = true; // 右边按钮监听 rightbtn.onclick = function () { // 判断锁的状态 if (!lock) return; lock = false; // 给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'; // 函数节流 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>
-
呼吸轮播图
<!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 { width: 650px; height: 360px; border: 1px solid #000; margin: 50px auto; 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 .leftbtn { position: absolute; left: 20px; top: 50%; margin-top: -25px; width: 50px; height: 50px; background-color: rgb(28, 180, 226); border-radius: 50%; } .carousel .rightbtn { position: absolute; right: 20px; top: 50%; margin-top: -25px; width: 50px; height: 50px; background-color: rgb(28, 180, 226); border-radius: 50%; } </style> </head> <body> <div class="carousel"> <ul id="list"> <li><img src="images/beijing/0.jpg" alt=""></li> <li><img src="images/beijing/1.jpg" alt=""></li> <li><img src="images/beijing/2.jpg" alt=""></li> <li><img src="images/beijing/3.jpg" alt=""></li> <li><img src="images/beijing/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 leftbtn = document.getElementById('leftbtn'); var rightbtn = document.getElementById('rightbtn'); var list = document.getElementById('list'); 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; }, 1000); } // 左按钮 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; }, 1000); } </script> </body> </html>
重点内容
- 访问元素节点有哪些方法?
- 节点的关系有哪些?
- 常用节点操作有哪些?
- 节点的创建、移除和克隆要如何实现?
- 事件捕获和冒泡是什么?应该如何设置?
- 什么是事件委托?什么时候要用事件委托?
- 使用定时器和CSS3的过度实现动画