js中clearInterval无效,以及setInterval中断后重新执行
引言:
網頁中的效果:網頁上向右運動的span,背景圖片隨著向右移動而不斷切換。在鼠標移入圖片時,停止向右運動,并改變為特定的背景圖片;當鼠標移出時,繼續向右移動并不斷切換背景圖片,直到運動到右端停止運動及圖片切換。向右運動以及圖片切換效果均是由setInterval周期性調用函數實現,停止運動則需要clearInterval函數實現。在實現過程中容易出現以下問題:
??? 鼠標移入時不能停止運動,或者是移動速度加快,clearInterval無效;鼠標移出后,運動到最右端不能停止,clearInterval無效;
導致出現這個問題的原因為:
setInterval()每執行一次,則返回一個唯一id。所以setInterval()執行了n次,那么需要調用clearInterval()也是n次。出現clearInterval()失效的情況,請查看每次調用setInterval()是否都clearInterval()了。
說明:對于本篇文章中涉及到的知識點,只做簡單說明,詳細信息請查找相關資料。 Demo演示:https://manmanliu.github.io/html/hwv8.html
一、布局
在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 | 設置是否及如何重復背景圖像 |
document.getElementById("wait").style.backgroundPositionY='0px';
三、向右移動
function runing()實現了一次向右移動一定偏移量,切換一次圖片,移動后判斷是否需要停止移動。通過setInterval()周期性的調用running(),實現不斷右移效果。
1、setInterval() 方法:
setInterval() 方法可按照指定的周期(以毫秒計)來調用函數或計算表達式。
setInterval() 方法會不停地調用函數,直到 clearInterval() 被調用或窗口被關閉。
由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的參數。
語法:setInterval(code,millisec[,"lang"])
| code | 必需。要調用的函數或要執行的代碼串。 |
| millisec | 必須。周期性執行或調用 code 之間的時間間隔,以毫秒計。 |
四、添加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(){ //如果不是第一次,則停止上一次的setIntervalif(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的返回Idvar 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 -> 60runChange(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(){//如果不是第一次,則停止上一次的setIntervalif(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>
總結
以上是生活随笔為你收集整理的js中clearInterval无效,以及setInterval中断后重新执行的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用户名、手机号码、邮箱、密码、验证码等验
- 下一篇: 微信小程序:获取用户手机号码的过程