引言:
網頁中的效果:網頁上向右運動的span,背景圖片隨着向右移動而不斷切換。在鼠標移入圖片時,停止向右運動,並改變爲特定的背景圖片;當鼠標移出時,繼續向右移動並不斷切換背景圖片,直到運動到右端停止運動及圖片切換。向右運動以及圖片切換效果均是由setInterval週期性調用函數實現,停止運動則需要clearInterval函數實現。在實現過程中容易出現以下問題:
鼠標移入時不能停止運動,或者是移動速度加快,clearInterval無效;鼠標移出後,運動到最右端不能停止,clearInterval無效;
導致出現這個問題的原因爲:
setInterval()每執行一次,則返回一個唯一id。所以setInterval()執行了n次,那麼需要調用clearInterval()也是n次。出現clearInterval()失效的情況,請查看每次調用setInterval()是否都clearInterval()了。
說明:對於本篇文章中涉及到的知識點,只做簡單說明,詳細信息請查找相關資料。
一、佈局
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;
}
主要涉及知識:position:absolute:絕對定位,它是脫離文檔流的。
position:relative:相對定位,不會脫離文檔流。
二、圖片切換效果
通過設置圖片在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++;
}
主要涉及知識:屬性 | 描述 |
---|---|
background | 在一行中設置所有的背景屬性 |
backgroundAttachment | 設置背景圖像是否固定或隨頁面滾動 |
backgroundColor | 設置元素的背景顏色 |
backgroundImage | 設置元素的背景圖像 |
backgroundPosition | 設置背景圖像的起始位置 |
backgroundPositionX | 設置backgroundPosition屬性的X座標 |
backgroundPositionY | 設置backgroundPosition屬性的Y座標 |
backgroundRepeat | 設置是否及如何重複背景圖像 |
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>
主要涉及知識: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(){
//如果不是第一次,則停止上一次的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);
}
主要涉及知識:
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可見
}
}
主要涉及知識: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>