引言:
网页中的效果:网页上向右运动的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