【JavaScript从入门到精通】第九课 定时器的使用-01
此内容来自开课吧石川微信公众号
从这节课开始我们讲定时器。定时器分为两种:
- setInterval 间隔型
- setTimeout 延时型
setInterval的第一个参数是函数,第二个函数是时间(单位为毫秒),其作用为每隔一段时间便执行一次函数。下面是一个简单例子:
function show() { alert('a'); } setInterval(show, 1000);
效果如下:
如果我们将上述函数的setInterval改为setTimeout,那么函数在执行一次之后就不会再次执行。setTimeout的两个参数与setInterval相同,其作用是在经过设定的时间后执行一次函数。
对于setInterval来说,如果我们不进行任何操作,那么它的工作是永久性的,所以有时候我们需要关闭它。关闭定时器的方法是使用clearInterval函数。但是,当一个页面存在多个定时器时,我们需要告诉clearInterval函数我们需要关闭的定时器是哪个。实际上,setInterval这个函数是有返回值的,只要我们将返回值用变量存储起来,在关闭定时器时使用该变量作为参数,clearInterval函数就可以得知关闭的定时器应该是哪个了。完整代码如下:
<html> <head> <meta charset="utf-8"> <title>无标题文档</title> </head> <body> <input id="btn1" type="button" value="开启"/> <input id="btn2" type="button" value="关闭"/> </body> </html>
window.onload = function () { var oBtn1 = document.getElementById('btn1'); var oBtn2 = document.getElementById('btn2'); var timer = null; oBtn1.onclick = function () { timer = setInterval(function () { alert('a'); }, 1000); }; oBtn2.onclick = function () { clearInterval(timer); }; };
同样的,对于setTimeout,关闭定时器的函数为clearTimeout。
现在我们通过定时器来做一个数码时钟,时钟的具体效果如下:
我们从布局开始分析这个时钟。首先,我们准备好了数字0-9的图片,分别命名为0.png至9.png存于当前路径下的img文件夹,用于显示数字,而实际上时钟时间的变化就是图片的切换。其次,为了让显示的时间为真实时间,我们需要用到Date对象来获取当前时间。
在JS里,Date对象有很多的方法和属性供大家使用。Date对象的最基本用法如下:
var oDate=new Date(); //定义Date对象 alert(oDate.getHours()); //获取时
new用于创建一个对象,而getHours方法可以返回当前是几点钟,同理还有getMinutes和getSeconds,分别用于获取当前分和获取当前秒。
回到我们的时钟上来,我们可以用一个字符串来储存当前的时分秒,并通过字符串控制图片的显示(第i张图片即是该字符串的第i位)。通过Date对象的getHours,getMinutes和getSeconds方法,我们很容易获取到当前的时分秒,但这里我们需要进行两个处理。首先用这些方法返回的数据类型是数值型,如果直接使用+进行拼接会变成数值相加,因此我们需要将数值转化为字符串。其次,当获取的数值为一位数时,前面不会有,但实际上我们显示时间时前面有0。综上所述,我们采用一个toDouble函数在把数值转化为字符串的同时将一位数补零。完成这些操作后,我们就获得了一个显示当前时间的时钟,但是只有刷新页面,时钟的时间才会发生变化。
为了让我们的时钟动起来,就需要用到setInterval。你大概也能猜到,只要把前面我们写的静态时钟作为一个函数放到setInterval里,然后设定时间为1000(毫秒,也就是1秒),时钟就可以自动运行啦。
到目前为止,整个程序的设计基本已经完成,但是还存在一个小问题:对于setInterval来说,它第一次执行是在页面打开之后经过我们设定的时间才会开始,也就是说我们的时钟在打开或刷新后一秒才会正式开始运转。为了解决这个问题,我们在window.load里将整个函数先执行一次,这样页面一打开,程序就会立马执行,不会再出现1秒的延迟。
全部代码如下:
<html> <head> <meta charset="utf-8"> <title>无标题文档</title> </head> <body style="background:black; color: white; font-size:50px;"> <img src="img/0.png"/> <img src="img/0.png"/> : <img src="img/0.png"/> <img src="img/0.png"/> : <img src="img/0.png"/> <img src="img/0.png"/> </body> </html>
function toDou(n) { if (n < 10) { return '0' + n; } else { return '' + n; } } window.onload = function () { var aImg = document.getElementsByTagName('img'); function tick() { var oDate = new Date(); var str = toDou(oDate.getHours()) + toDou(oDate.getMinutes()) + toDou(oDate.getSeconds()); for (var i = 0; i < aImg.length; i++) { aImg[i].src = 'img/' + str.charAt(i) + '.png'; } } setInterval(tick, 1000); tick(); };
最后的最后,我们仍然要补充一个兼容性问题。如果你将这段代码放在IE7下运行,所有的图片都会加载不出来。这是为什么呢?在这个例子里,我们采用str[i]的方法获取了字符串第i位的字符,但这种写法在IE7下是不兼容的,只有高版本的浏览器支持这种写法。为了满足所有浏览器,我们使用更加兼容的一种方式:str.charAt(i)。 因此我们将上面拼接图片路径的代码改为:
aImg[i].src='img/'+src.charAt(i)+'.png';
这样,就不会出现兼容性问题了。
Date对象的其他方法
刚才我们学习了Date对象获取时分秒的方法,实际上Date对象还有很多的方法:
- getFullYear(),获取当前年份。
- getMonth(),获取当前月,不过JS里的月是从0开始,因此我们在使用是通常将getMonth+1使用。
- getDate() 获取当前日。
- getDay() 获取当前星期,其值为0-6,由于国外的一周都是从周日算起,所以分别代表周日-周六。
延时提示框
我们在第一课就讲过鼠标提示框,但很多时候,当我们的鼠标离开元素的时候,提示框并不是立马消失而是过一段时间消失,同时我们还希望,当我们的鼠标移动到提示框的时候,提示框能够一直存在。为了达成这样延时提示框的效果就要用到setTimeout定时器。
<html> <head> <meta charset="utf-8"> <title>无标题文档</title> </head> <body> <div id="div1"></div> <div id="div2"></div> </body> </html>
div { float: left; margin: 10px; } #div1 { width: 50px; height: 50px; background: red; } #div2 { width: 250px; height: 180px; background: #CCC; display: none; }
window.onload = function () { var oDiv1 = document.getElementById('div1'); var oDiv2 = document.getElementById('div2'); oDiv1.onmouseover = function () { oDiv2.style.display = 'block'; }; oDiv1.onmouseout = function () { oDiv2.style.display = 'none'; }; };
这段代码里,当我们移出鼠标时,div2会立马消失。在onmouseout事件里,我们使用setTimeout定时器让其在一定时间后再消失。
oDiv1.onmouseout=function () { timer=setTimeout(function (){ oDiv2.style.display='none'; }, 500); };
这样就可以实现延时消失功能,但存在这么一个问题:当我们将鼠标从div1移动到div2时,div2依然会在定时器触发后消失,因此当我们鼠标移入到div2时我们需要使用onmouseover时间将定时器关闭。
window.onload=function () { var oDiv1=document.getElementById('div1'); var oDiv2=document.getElementById('div2'); var timer=null; oDiv1.onmouseover=function () { clearTimeout(timer); oDiv2.style.display='block'; }; oDiv1.onmouseout=function () { timer=setTimeout(function (){ oDiv2.style.display='none'; }, 500); }; oDiv2.onmouseover=function () { clearTimeout(timer); //关闭定时器 }; oDiv2.onmouseout=function () { timer=setTimeout(function (){ oDiv2.style.display='none'; }, 500); }; };
最后一个问题是,这种情况下我们再将鼠标移出div2时,div2并不会消失,因此还需要给div2添加鼠标移出时的定时器让它消失。同时,我们发现div2和div1的onmouseover和onmouseout事件内的代码完全一致,因此可以通过连等的方式将它们合并。
window.onload=function () { var oDiv1=document.getElementById('div1'); var oDiv2=document.getElementById('div2'); var timer=null; oDiv2.onmouseover=oDiv1.onmouseover=function () { clearTimeout(timer); oDiv2.style.display='block'; }; oDiv2.onmouseout=oDiv1.onmouseout=function () { timer=setTimeout(function (){ oDiv2.style.display='none'; }, 500); }; };
这样就完成了我们延时提示框的全部完善功能,效果如下:
如需转载,烦请注明出处:https://www.qdskill.com/javascript/501.html