马黑黑 发表于 2022-3-4 23:23

JS定时器

本帖最后由 马黑黑 于 2022-3-5 22:22 编辑

所谓定时器,和我们生活中定时器的原理一样。比如洗衣机的洗涤预约,就用上定时器,我们可以设定一个时间,这个时间一到,洗衣机就会自动工作,直至工作做完。

定时器通常会有至少两种工作机制:

其一:一次性的工作机制。即,设定一次,它工作一次,然后就没了。

其二:重复性的工作机制。即,一旦设定,除非解除,否则时间一到,它就自动进入工作状态。

JS同样拥有这两种工作机制的定时器:

其一:setTimeout() 计时器 - 一次性工作机制的定时器

其二:setInterval()计时器 - 重复性工作机制的定时器

语法也差不多:

setTimeout("js语句", 毫秒);
setInterval("js语句", 毫秒);

每一种计时器也都有取消机制:

clearTimeout(定时器句柄);
clearInterval(定时器句柄);

实例:我们设计了两个div盒子,分别接收两中计时器的计时消息,这两个计时消息都分别是间隔1秒钟给各自的计时变量加1,以比较两种计时器不同的工作机制。我们还用上了两个按钮,可以通过它们来关闭和开启定时器。

代码有些复杂,变量不少,自定义函数也有好几个:

<div id="setInterval">setInterval计时器:0</div>
<div id="setTimeout">setTimeOut计时器:0</div>
<br><br><input id="stop" type="button" value="关闭定时器" />
<input id="start" type="button" value="开启定时器" disabled="disabled" />


<script language="javascript">

var time1 = 0;
var time2 = 0;
var T1= setInterval(calTime1,1000);
var T2 = setTimeout(calTime2,1000);

function calTime1(){
      time1 = time1 + 1; //间隔一秒钟自动加 1
      document.getElementById('setInterval').innerHTML = "setInterval计时器 : " + time1;
};

function calTime2(){
      time2 = time2 + 1; //间隔一秒钟自动加 1
      document.getElementById('setTimeout').innerHTML = "setTimeout计时器 : " + time2;
};

//关闭定时器
function closeTimer(){
      clearInterval(T1);
      clearTimeout(T2);
      document.getElementById('start').disabled = false;
      document.getElementById('stop').disabled = true;
}

//开启定时器
function startTimer(){
      T1 = setInterval(calTime1,1000);
      T2 = setTimeout(calTime2,1000);
      document.getElementById('start').disabled = true;
      document.getElementById('stop').disabled = false;
}
</script>

马黑黑 发表于 2022-3-4 23:25

本帖最后由 马黑黑 于 2022-3-4 23:27 编辑 <br /><br /><div id="setInterval">setInterval计时器:0</div>
<div id="setTimeout">setTimeOut计时器:0</div>
<br><br><input id="stop" type="button" value="关闭定时器" onclick="closeTimer();" />
<input id="start" type="button" value="开启定时器" onclick="startTimer();" disabled="disabled" />

<script language="javascript">

var time1 = 0;
var time2 = 0;
var T1= setInterval(calTime1,1000);
var T2 = setTimeout(calTime2,1000);

function calTime1(){
        time1 = time1 + 1; //间隔一秒钟自动加 1
        document.getElementById('setInterval').innerHTML = "setInterval计时器 : " + time1;
};

function calTime2(){
        time2 = time2 + 1; //间隔一秒钟自动加 1
        document.getElementById('setTimeout').innerHTML = "setTimeout计时器 : " + time2;
};

//关闭定时器
function closeTimer(){
        clearInterval(T1);
        clearTimeout(T2);
        document.getElementById('start').disabled = false;
        document.getElementById('stop').disabled = true;
}

//开启定时器
function startTimer(){
        T1 = setInterval(calTime1,1000);
        T2 = setTimeout(calTime2,1000);
        document.getElementById('start').disabled = true;
        document.getElementById('stop').disabled = false;
}
</script>

马黑黑 发表于 2022-3-4 23:38

本帖最后由 马黑黑 于 2022-3-5 22:30 编辑

代码说明:


HTML部分:


<div id="setInterval">setInterval计时器:0</div>
<div id="setTimeout">setTimeOut计时器:0</div>
<br><br><input id="stop" type="button" value="关闭定时器" onclick="closeTimer();" />
<input id="start" type="button" value="开启定时器" onclick="startTimer();" disabled="disabled" />


两个div盒子,一个用于显示setInterval计时器计数结果,一个用于显示setTimeout计时器计数结果,都有自己的id标识号。

两个按钮,一个用于关闭定时器,一个用于开启定时器。我编写的JS程序一开始就计时,所以关闭按钮放在前面,关闭了还是可再开启并继承原先已有的计时结果。两个按钮不能同时都处于可用状态,所以HTML代码里,开启定时器按钮设置成了不可用,然后由JS代码来决定将来它们的可用状态。

JavaScript部分:

我首先定义两个用于装载计数结果的变量 time1 和 time2,分别由于记录 setInterval 和 setTimeout 定时器的计数:

var time1 = 0;
var time2 = 0;


接着,我又声明两个变量 T1 和 T2,它们分别是两个定时器的操作句柄,且分别隔 1000 毫秒(即1秒)执行一个自定义函数:

var T1= setInterval(calTime1,1000);
var T2 = setTimeout(calTime2,1000);


calTime1 和 calTime2 其实是两个自定义函数,本应写为 calTime1() 和 calTime2() ,由于 setInterval 和 setTimeout 语法规范的关系,JS语句参数即第一个参数如果不用引号,则不能带参数,也不能带括号;如果需要带括号和(或)参数,则需要写成:

var T1= setInterval("calTime1()",1000);
var T2 = setTimeout("calTime2()",1000);


两个自定义函数其实很简单:

function calTime1(){
      time1 = time1 + 1; //间隔一秒钟自动加 1
      document.getElementById('setInterval').innerHTML = "setInterval计时器 : " + time1;
};


function calTime2(){
      time2 = time2 + 1; //间隔一秒钟自动加 1
      document.getElementById('setTimeout').innerHTML = "setTimeout计时器 : " + time2;
};


它们只作两件事:一是给前面定义的变量 time1 和 time2 加 1,然后在不同的div盒子里按预定文本设定显示它们。这两个函数分别被 T1 和 T2 定时器操作句柄调用,调用事件间隔是1秒(1000毫秒)。

我在此例中还演示了关闭定时器的方法,分别用 clearInterval() 和 clearTimeout() 方法,它们只需要一个参数,定时器操作句柄变量(就是T1 和 T2)。

//关闭定时器
function closeTimer(){
      clearInterval(T1);
      clearTimeout(T2);
      document.getElementById('start').disabled = false;
      document.getElementById('stop').disabled = true;
}


上面的代码同时还处理两个按钮的可用状态。

关闭了定时器还可以重新开启,并可继承之前的计数结果:

//开启定时器
function startTimer(){
      T1 = setInterval(calTime1,1000);
      T2 = setTimeout(calTime2,1000);
      document.getElementById('start').disabled = true;
      document.getElementById('stop').disabled = false;
}


T1 和 T2 句柄变量无需再声明,这是之前声明过的,这里重新赋值而已。这样能延续使用计时器,同时可以再度关闭、开启,关闭与开启可以无限循环。同样的,开启定时器函数也要处理一下两个按钮的可用状态。

关闭和开启定时器的两个函数,由两个按钮的 onclick 事件调用。

小结:代码虽略显复杂,其实没啥难度,只是依据定时器相关的方法与参数封装了几个简单的函数然后调用。

红影 发表于 2022-3-5 07:58

setInterval(calTime1,1000),括号里的设置是什么意思?我等了一会了,超过1000后,那个计时器还在走。

红影 发表于 2022-3-5 09:05

<input id="stop" type="button" value="关闭定时器" />这句会自动出现那个小方框?

红影 发表于 2022-3-5 09:06

马黑黑 发表于 2022-3-4 23:38
解释占位(有空再写说明)

很多不懂的,等着看详细解答。黑黑辛苦了,那么晚还在写教程{:4_190:}

马黑黑 发表于 2022-3-5 21:44

红影 发表于 2022-3-5 09:05
这句会自动出现那个小方框?

input是个标签集合,依据 type 值显示不同的样式,如按钮(button)、单选框(radio)等等

马黑黑 发表于 2022-3-5 21:50

红影 发表于 2022-3-5 07:58
setInterval(calTime1,1000),括号里的设置是什么意思?我等了一会了,超过1000后,那个计时器还在走。

一楼有讲到 setInterval() 方法,它有两个参数,第一个是JS语句,第二个是毫秒数。

关于calTime,是我在本例中自定义的函数,setInterval() 方法引用这个函数,引用方法之一是函数名,也可以用引号引起来:

setInterval("calTime1()", 1000);

这个时候,这样的引用可带参数(如有),参数放在括号里。

关于毫秒数,1000毫秒等于一秒,大于一千的设定定时器当然也会走,无限大也会走,只要你可以等待。

红影 发表于 2022-3-5 22:41

马黑黑 发表于 2022-3-5 21:44
input是个标签集合,依据 type 值显示不同的样式,如按钮(button)、单选框(radio)等等

哦哦,原来是这样。

红影 发表于 2022-3-5 22:44

马黑黑 发表于 2022-3-5 21:50
一楼有讲到 setInterval() 方法,它有两个参数,第一个是JS语句,第二个是毫秒数。

关于calTime,是我 ...

原来1000是时间间隔,而且单位是毫秒。还以为是上限1000秒呢,弄错了。

马黑黑 发表于 2022-3-5 22:47

红影 发表于 2022-3-5 22:44
原来1000是时间间隔,而且单位是毫秒。还以为是上限1000秒呢,弄错了。

一楼有语法的

马黑黑 发表于 2022-3-5 22:48

红影 发表于 2022-3-5 22:41
哦哦,原来是这样。

知识点很繁杂的吧

红影 发表于 2022-3-5 23:08

马黑黑 发表于 2022-3-5 22:47
一楼有语法的

一楼说了单位,没说是是做什么用的啊。

红影 发表于 2022-3-5 23:08

马黑黑 发表于 2022-3-5 22:48
知识点很繁杂的吧

仔细看觉得还行。

马黑黑 发表于 2022-3-6 08:23

红影 发表于 2022-3-5 23:08
仔细看觉得还行。

甚好{:5_108:}

马黑黑 发表于 2022-3-6 09:40

本帖最后由 马黑黑 于 2022-3-6 10:34 编辑 <br /><br /><input id="load" type="button" value=" 加载图片 " /><br><br>
<canvas id="gImg" width="800" height="800" style="position:relative;left:-21px;"></canvas>

<script language="javascript">
document.getElementById('load').onclick = function(){
        var dh = 0;
        var step = 1;
        var gpic = new Image;
        var cc = document.getElementById('gImg');
        var ct = cc.getContext('2d');
        gpic.onload = function(){
                var tt = setInterval(function(){
                        ct.clearRect(0, 0, 800, 800);
                        ct.drawImage(gpic, 0, 0, 800, dh, 0, 0, 800, dh);
                        dh = dh + step;
                        if(dh > 800){
                                clearInterval(tt);
                                //this.disabled = false;
                        }
                },1)
        }
        gpic.src = "/data/attachment/forum/202203/06/082517mir1rxiwvzqvxqfd.jpg";
}

</script>

马黑黑 发表于 2022-3-6 10:12

本帖最后由 马黑黑 于 2022-3-6 12:29 编辑

上楼代码及解释:

<input id="load" type="button" value=" 加载图片 " /><br><br>
<canvas id="gImg" width="800" height="800" style="position:relative;left:-21px;"></canvas>

<script language="javascript">
//按钮点击事件
document.getElementById('load').onclick = function(){
      var dh = 0; //高度监测变量
      var step = 1; //步进变量:为1等于逐行扫描和作画
      var gpic = new Image; //创建图像对象
      var cc = document.getElementById('gImg'); //画布标识
      var ct = cc.getContext('2d'); //画笔标识
      gpic.onload = function(){ //图片加载后事件
                var tt = setInterval(function(){ //定时器匿名函数
                        ct.clearRect(0, 0, 800, 800); //清除画布上的一切
/* 下面一句是画图,每次都:
    ① 从原始图像{0,0}处截取800像素宽度、dh像素高度的图像;
    ② 在画布上从{0,0}处画到画布上的800px的宽度、dh像素的高度
*/
                        ct.drawImage(gpic, 0, 0, 800, dh, 0, 0, 800, dh);
                        dh = dh + step; //行高步进
                        if(dh > 800){ //若 行高 > 800 则
                              clearInterval(tt); //关闭定时器
                        }
                },1)
      }
      gpic.src = "/data/attachment/forum/202203/06/082517mir1rxiwvzqvxqfd.jpg"; //图像对象地址
}

</script>

红影 发表于 2022-3-6 11:36

马黑黑 发表于 2022-3-6 10:12
上楼代码及解释:




这个就是那个让东篱大哥等到美女的帖子的代码吧{:4_189:}

马黑黑 发表于 2022-3-6 11:38

红影 发表于 2022-3-6 11:36
这个就是那个让东篱大哥等到美女的帖子的代码吧

女孩子是,实现机制有所不同:这里是逐行扫描、作画,那里是隔10秒钟作画

马黑黑 发表于 2022-3-6 12:28

红影 发表于 2022-3-5 23:08
一楼说了单位,没说是是做什么用的啊。

毫秒是间隔时间参数,也可以看成是暂停时间参数,意思就是,这个时间参数一到就干点什么。其中,setTimeout做一次就不做了,setInterval会重复着按这个间隔时间去做
页: [1] 2 3 4 5
查看完整版本: JS定时器