js中clearInterval无效,以及setInterval中断后重新执行

引言:

网页中的效果:网页上向右运动的span,背景图片随着向右移动而不断切换。在鼠标移入图片时,停止向右运动,并改变为特定的背景图片;当鼠标移出时,继续向右移动并不断切换背景图片,直到运动到右端停止运动及图片切换。向右运动以及图片切换效果均是由setInterval周期性调用函数实现,停止运动则需要clearInterval函数实现。

在实现过程中容易出现以下问题:

鼠标移入时不能停止运动,或者是移动速度加快,clearInterval无效;鼠标移出后,运动到最右端不能停止,clearInterval无效;

导致出现这个问题的原因为:

setInterval()每执行一次,则返回一个唯一id。所以setInterval()执行了n次,那么需要调用clearInterval()也是nci。出现clearInterval()失效的情况,请查看每次调用setInterval()是否都clearInterval()了。

本篇文章中,通过对该效果的实现,解决这两个问题。

说明:对于本篇文章中涉及到的知识点,只做简单说明,详细信息请查找相关资料。

一、布局

在head中引用css文件,body中,主要为一个div,为主要显示效果区域,id="show",position属性设置为relative,让其他元素以此为基准进行定位;show中为三个span,id分别为run,wait,end;在run中,实现图片的右移和图片切换,以及鼠标移入时停止移动并切换鼠标移入时的背景图片,移动到右端wait处停止移动;wait在右端切换图片,直到run移动到该处时,与run一起不可见,同时,end可见。

html代码片段:

<div id="show">
	<span class="showbody" id="run" onMouseOver="mouseOver()" onMouseOut="mouseOut()"></span>
	<span class="showbody" id="end"></span>
	<span class="showbody" id="wait"></span>
</div>

css代码片段:

#show{
	position:relative;
	top:100px;
	height:100px;
	margin:auto;
	border-bottom:4px solid green;
}	

.showbody{
	height:40px;
	position:absolute;
	display:block;
	bottom:0px;
	background-repeat:no-repeat;
}
.run{
	background-image:url(../img/run.png) ;
	background-position:0px 0px;
	width:226px;
	height:40px;
}
.wait{
	background-image:url(../img/wait.png) ;
	background-position:0px 0px;
	width:90px;
	height:56px;
	right:0px;
}
.end{
	background-image:url(../img/end.png) ;
	width:90px;
	height:56px;
	right:0px;
	visibility:hidden;
}

主要涉及知识:

1、相对定位与绝对定位:

position:absolute:绝对定位,它是脱离文档流的。

position:relative:相对定位,不会脱离文档流。

2、设置单边效果:

border-bottom:4px solid green;//设置底部边框为实线,其他边框不可见。

3、行内元素与块级元素:

display:block;//由于span为行内元素,设置其宽、高等属性无效。

二、图片切换效果

通过设置图片在Y轴方向上的位置,来实现图片的切换,以wait为示例代码,run的切换为

//wait背景图片切换
var waitD= document.getElementById("wait");
var waitFlag = 0;
function waiting(){
	if(waitFlag%4==0){
		waitD.style.backgroundPositionY='0px';
	}else if(waitFlag%4==1){
		waitD.style.backgroundPositionY='-56px';
	}else if(waitFlag%4==2){
		waitD.style.backgroundPositionY='-112px';
	}else if(waitFlag%4==3){
		waitD.style.backgroundPositionY='-168px';
	}
	waitFlag++;
}

主要涉及知识:

1、文档流中坐标图以左上角为原点,向下为Y轴的正方向,向右为X轴的正方向,显示器正面为Z轴正方向,如下所示:

类似于高中数学XYZ轴三维空间模型:数学中,向上为Y轴正方向;在文档流中,向下为Y轴正方向。

2、HTML DOM Style 对象的Background
属性:

属性 描述
background 在一行中设置所有的背景属性
backgroundAttachment 设置背景图像是否固定或随页面滚动
backgroundColor 设置元素的背景颜色
backgroundImage 设置元素的背景图像
backgroundPosition 设置背景图像的起始位置
backgroundPositionX 设置backgroundPosition属性的X坐标
backgroundPositionY 设置backgroundPosition属性的Y坐标
backgroundRepeat 设置是否及如何重复背景图像

本示例中主要用backgroundPositionY,来改变图片的显示:

document.getElementById("wait").style.backgroundPositionY=‘0px‘;

三、向右移动

function runing()实现了一次向右移动一定偏移量,切换一次图片,移动后判断是否需要停止移动。通过setInterval()周期性的调用running(),实现不断右移效果。

/<span style="font-size:14px;">/向右移动
var runDiv = document.getElementById("run");
function runing(){
		var r = 80;//向右移动的偏移量--即每次右移80px
		//1 向右运动
		runDiv.style.left = runDiv.offsetLeft+r+"px";//run的左边距设置为run的宽度+80px,即每次右移80px

		//2 图片切换
		var left = parseInt(runDiv.style.left);//将返回的像素字符串转换为数字,如60px -> 60
		runChange(left,r);//run图片切换

		//4 是否停止运动,停止时end可见
		runStop(left);
	}</span>

主要涉及知识:

1、setInterval()
方法:

setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。

setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。

由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。

语法:setInterval(code,millisec[,"lang"])

参数 描述
code 必需。要调用的函数或要执行的代码串。
millisec 必须。周期性执行或调用 code 之间的时间间隔,以毫秒计。

返回值:一个可以传递给 Window.clearInterval()
从而取消对 code 的周期性执行的值。

本示例中,通过调用方法setInterval()周期性的调用图片切换函数,来实现向右移动过程中不断切换图片的效果和右端不断切换的效果。

四、添加mouse事件

鼠标移入,run停止右移,背景图片换位特定的图片;鼠标移出,run继续右移,背景图片继续切换;

其中使用clearInterval()
方法时需要注意的是:clearInterval()
方法的参数必须是由 setInterval() 返回的 ID 值。这一点很重要!!

进入页面,setInterval()调用runing()方法,使run向右移动;在鼠标移入时,调用clearInterval()清除setInterval()
设置的 timeout,移出时setInterval()继续调用runing()方法向右移动。鼠标移出时setInterval()返回的id与刚进入页面时setInterval()返回的id,是两个id,即setInterval()每执行一次,则返回一个唯一id。所以setInterval()执行了n次,那么需要调用clearInterval()也是nci。出现clearInterval()失效的情况,请查看每次调用setInterval()是否都clearInterval()了。

本示例中,mouseOver()中调用setInterval();mouseOut()中调用clearInterval()。用mouseOutFlag来标记是否有鼠标移出事件。在鼠标移入时,判断在本次鼠标移入之前,是否有鼠标移出,如果有,则调用clearInterval(),取消由
setInterval() 设置的 timeout。目的是确保只有setIntervalsetInterval一个setInterval()调用runing()方法。

//鼠标移入时,更换背景图片图片,停止运动
var intR1=0;//mouseOut()处调用setInterval的返回Id
var mouseOutFlag=0;//是否调用mouseOut()标志
function mouseOver(){
//如果不是第一次,则停止上一次的setInterval
	if(mouseOutFlag!=0){
		window.clearInterval(intR1);
	}
	runDiv.style.backgroundImage="url(./img/hover.png)";//设置背景图片
	runDiv.style.backgroundPositionY='0px';//设置图片在Y轴上的位置
	runDiv.style.backgroundPosition='center center';//设置图片位置为上下居中,左右居中
	window.clearInterval(intR);
}
//鼠标移出时,继续向右移动,图片继续切换
function mouseOut(){
	mouseOutFlag=1;
	//run从停止的地方继续运动,且图片从停止的地方继续切换
	runDiv.style.backgroundImage="url(./img/run.png)";//设置设置背景图片
	runDiv.style.backgroundPositionY='0px';//设置图片在Y轴上的位置
	//从停止的地方继续向右移动
	intR1=self.setInterval("runing()",400);
}

主要涉及知识:

1、onMouseOver事件属性:当鼠标指针移动到图像上时执行一段 JavaScript;

2、onMouseOut事件属性:当鼠标指针移出图像时执行一段 JavaScript;

3、clearInterval()方法:

clearInterval() 方法可取消由 setInterval() 设置的 timeout。

clearInterval() 方法的参数必须是由 setInterval() 返回的 ID 值。

语法:clearInterval(id_of_setinterval)

参数 描述
id_of_setinterval 由 setInterval() 返回的 ID 值。

五、移动到右端停止

1、判断移动到右端:run的左外边距小于等于show的宽度减去wait的宽度;

2、使用window.clearInterval(intR),停止run的向右移动以及图片切换,同时visibility属性设置为不可见;wait停止图片切换,visibility属性设置为不可见;end的visibility属性设置为可见。

停止移动时,也需要判断是否有鼠标移出事件中的setInterval(),如果有,则需要调用clearInterval()来停止右移

//停止<span style="font-family:Microsoft YaHei;">移</span>动
function runStop(left){
	var showWidth = parseInt(document.getElementById("show").offsetWidth);//获取show的宽度
	var runWidth = parseInt(runDiv.offsetWidth);//获取run的宽度
	if(left==(showWidth-runWidth) || left>(showWidth-runWidth)){//运动到靠近end时:run的左外边距,小于等于。。。
		if(mouseOutFlag==1){//调用了mouseOut()函数,则停止
			window.clearInterval(intR1);
		}
		window.clearInterval(intR);//从mouseOut()处停止调用runing函数
		window.clearInterval(intW);//停止调用waiting函数
		runDiv.style.visibility="hidden";//run不可见
		waitD.style.visibility="hidden";//wait也不可见
		document.getElementById("end").style.visibility="visible";//end可见
	}
}

主要涉及知识:

1、parseInt("1px");//将返回的像素字符串转换为数字--->结果1

2、document.getElementById("run").style.left="1px";//设置run的左边距

3、document.getElementById("show").offsetWidth;//获取show的宽度

4、document.getElementById("run").style.visibility="hidden";//run不可见

5、clearInterval()方法。

完整的代码如下所示:

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus®">
  <meta name="Author" content="">
  <meta name="Keywords" content="">
  <meta name="Description" content="">
  <title>HUAWEI-V8</title>
  <link rel="stylesheet" href="css/V8.css" type="text/css" />
 </head>
 <body>
   <div id="show">
		<span class="run showbody" id="run" onMouseOver="mouseOver()" onMouseOut="mouseOut()"></span>
		<span class="end showbody" id="end"></span>
		<span class="wait showbody" id="wait"></span>
    </div>

<script>
	var runDiv = document.getElementById("run");
	var waitD= document.getElementById("wait");
	var waitFlag = 0;

	//按照指定的周期(以毫秒计)来调用函数或计算表达式。
	var intW=self.setInterval("waiting()",400);
	var intR=self.setInterval("runing()",400);//每400毫秒调用一次runing()函数,实现run位置的右移
	var intR1=0;//mouseOut()处调用setInterval的返回Id
	var mouseOutFlag=0;//是否调用mouseOut()标志

	//向右移动
	function runing(){
		var r = 80;//向右移动的偏移量--即每次右移80px
		//1 向右运动
		runDiv.style.left = runDiv.offsetLeft+r+"px";//run的左边距设置为run的宽度+80px,即每次右移80px

		//2 图片切换
		var left = parseInt(runDiv.style.left);//将返回的像素字符串转换为数字,如60px -> 60
		runChange(left,r);//run图片切换

		//4 停止运动,end可见
		runStop(left);
	}

	//run背景图片切换
	function runChange(left,r){
		if((left/r)%3==0){
			runDiv.style.backgroundPositionY='0px';
		}else if((left/r)%3==1){
			runDiv.style.backgroundPositionY='-40px';
		}else if((left/r)%3==2){
			runDiv.style.backgroundPositionY='-80px';
		}
	}

	//停止运动
	function runStop(left){
		var showWidth = parseInt(document.getElementById("show").offsetWidth);//获取show的宽度
		var runWidth = parseInt(runDiv.offsetWidth);//获取run的宽度
		if(left==(showWidth-runWidth) || left>(showWidth-runWidth)){//运动到靠近end时:run的左外边距,小于等于。。。
			if(mouseOutFlag==1){//调用了mouseOut()函数,则停止
				window.clearInterval(intR1);
			}
			window.clearInterval(intR);//从mouseOut()处停止调用runing函数
			window.clearInterval(intW);//停止调用waiting函数
			runDiv.style.visibility="hidden";//run不可见
			waitD.style.visibility="hidden";//wait也不可见
			document.getElementById("end").style.visibility="visible";//end可见
		}
	}
	//wait背景图片切换
	function waiting(){
		if(waitFlag%4==0){
			waitD.style.backgroundPositionY='0px';
		}else if(waitFlag%4==1){
			waitD.style.backgroundPositionY='-56px';
		}else if(waitFlag%4==2){
			waitD.style.backgroundPositionY='-112px';
		}else if(waitFlag%4==3){
			waitD.style.backgroundPositionY='-168px';
		}
		waitFlag++;
	}
	//鼠标移入时,更换背景图片图片,停止运动
	function mouseOver(){
		//如果不是第一次,则停止上一次的setInterval
		if(mouseOutFlag!=0){
			window.clearInterval(intR1);
		}
		runDiv.style.backgroundImage="url(./img/hover.png)";//设置背景图片
		runDiv.style.backgroundPositionY='0px';//设置图片在Y轴上的位置
		runDiv.style.backgroundPosition='center center';//设置图片位置为上下居中,左右居中
		window.clearInterval(intR);
	}
	//鼠标移出时,继续向右移动,图片继续切换
	function mouseOut(){
		mouseOutFlag=1;
		//run从停止的地方继续运动,且图片从停止的地方继续切换
		runDiv.style.backgroundImage="url(./img/run.png)";//设置设置背景图片
		runDiv.style.backgroundPositionY='0px';//设置图片在Y轴上的位置
		//从停止的地方继续向右移动
		intR1=self.setInterval("runing()",400);
	}
</script>

</body>
</html>

全部资源链接:https://pan.baidu.com/s/1eSHh3AM,提取码:swfi

时间: 2024-08-02 14:06:28

js中clearInterval无效,以及setInterval中断后重新执行的相关文章

JS中的间歇调用setInterval()与超时调用setTimeout()相关总结

超时调用需要使用window.setTimeout(code,millisec)方法 它接受两个参数:要执行的代码和以毫秒表示的时间(即在执行代码前需要等待多少毫秒).其中第一个参数可以是一个包含JS代码的字符串(就和在eval()函数中使用的字符串一样),也可以是一个函数.第二个参数表示等待多长时间的毫秒数,但经过该事件后指定的代码不一定会执行. 这是因为JS是一个单线程序的解释器,一定时间内只能执行一段代码,为了控制要执行的代码就有一个JS任务队列,这些任务会按照将他们添加到队列的顺序执行.

JS中的setTimeout和setInterval的区别

学了许久的javascript,发现其中非常常用的两个函数,就是setInterval和setTimeout函数,对这两个函数的理解,有时觉得很模糊,经过多次的试验,终于对它有了比较深入的了解.定义,setInterval()-- 间隔指定的毫秒数不停地执行指定的代码.setTimeout,延迟两秒调用函数,这个定义非常的简单,但是它并不像字面意思上那么的简 很多人都觉得这两个方法差不多,但是,实际上,他们差的很远呢     因为setTimeout(表达式,延时时间)在执行时,是在载入后延迟指

setInterval中this

今天使用react做钟表,自然用到了setInterval,但是出现this指向不明的问题. 1 <html> 2 <head> 3 <meta charset="UTF-8" /> 4 <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script> 5 <script src="

QML中实现setTimeout和setInterval

Qt的QML中,js未提供setTimeout和setInterval,可以通过下面的代码实现. Timer {id: timer} function setTimeout(cb,delayTime) { //timer = new Timer(); timer.interval = delayTime; timer.repeat = false; timer.triggered.connect(cb); timer.start(); } https://my.oschina.net/lieef

在JS中,将text框中数据格式化,根据不同的小数位数,格式化成对应的XXX,XXX,XXX.XX(2位小数) 或者XXX,XXX,XXX(0位小数)

//在JS中,将text框中数据格式化,根据不同的小数位数,格式化成对应的XXX,XXX,XXX.XX(2位小数) 或者XXX,XXX,XXX(0位小数) function formatNum(num, n) {//参数说明:num 要格式化的数字 n 保留小数位 num = String(num.toFixed(n)); var re = /(-?\d+)(\d{3})/; while (re.test(num)) num = num.replace(re, "$1,$2") ret

js实现随机选取[10,100)中的10个整数,存入一个数组,并排序。 另考虑(10,100]和[10,100]两种情况。

1.js实现随机选取[10,100)中的10个整数,存入一个数组,并排序. 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 </head> 7 <body> 8 <script type="text/java

js如何计算一个字符在字符串中出现的次数

js如何计算一个字符在字符串中出现的次数:在实际应用中可能要计算一个字符在字符串中出现的次数,实现此功能的方式有多种,下面就介绍一个非常简单的方式.代码实例如下: function func(str,char) { var str=str; var num=(str.split(char)).length-1; return num } document.write(func("abcdefga","a")); 以上代码可以实现计算一个字符串中指定字符出现的次数.相

与正则有关的JS方法结合其在项目中的应用

与正则有关的JS方法结合其在项目中的应用 前言 最近项目中用到正则匹配比较多,因此打算深入理解和总结下各个与正则有关的方法,再结合在项目中使用的情况.与正则有关的JS方法共有7个,分别是RegExp对象的compile(), exec(), test() 和支持正则表达式的的String()方法为search(), match(), replace(), split(). RegExp对象方法 compile()方法 该方法用于改变和重新编译正则表达式.语法: RegExpObject.comp

js查找一篇英文文章中出现频率最高的单词

下面这个函数是js查找一篇英文文章中出现频率最高的单词(由26个英文字母大小写构成),输出该单词及出现次数,不区分大小写,主要是正则的运用: function counts(article){ article = article.trim().toUpperCase(); var array = article.match(/[A-z]+/g); article = " "+array.join(" ")+" "; var max = 0,wor