您的位置:首頁>正文

「js高手之路」打造通用的勻速運動框架

本文我們把上文的animate函數, 繼續改造, 讓他變得更加的通用和強大:

1, 支援多個物體的運動

2, 同時運動

3, 順序運動

這三種運動方式也是jquery中animate函數支援的

一、animate函數中怎麼區分變化不同的樣式?

上文中, 側邊欄效果 用的animate函數 改變的是left值

淡入淡出效果 用的animate函數 改變的是透明度

而我們封裝的函數, 要變成通用的, 首先面臨的問題就是 這個函數要同時支援left值和透明度的變化, 更通用的做法應該是要支援所有的樣式變化, 比如輪播功能, 他有左右滑動, 也有上下滑動。

我們可以在獲取樣式和改變樣式的時候, 做一下判斷就可以了, 判斷分2類就能達到目的, 因為其他樣式( margin, left, top, right, font-size等等 )都是px, 而透明度沒有px單位。

合併之後的animate相比之前多了一個參數attr, 這個參數就是變化的樣式, obj: 變化的物件, target: 樣式需要變化到的目標值. speed: 樣式每次變化的大小

如:

oImg.onmouseover = function () {

animate(this, 'opacity', 100, 10);

}

oImg是獲取到的圖片物件. 這裡各參數意思如下:

this:當前圖片物件

opacity: 變化的樣式是透明度

100: 滑鼠移到圖片上時, 透明度變成100

10: 透明度每次在原來的基礎上加10

View Code

上述就是完整的代碼實例, 請自行展開, 點擊run code預覽效果

run code

當你分別測試這兩個功能的時候:

移動到圖片上然後移出來

移動到分享到, 然後移出來

這樣是沒有問題的

如果你這樣測試:

移動到 分享到, 然後迅速又移動到圖片上, 這個時候你會發現 分享到 停下來了, 這就不符合邏輯了! 按道理來說, 滑鼠移動到圖片上, 相當於觸發了 “分享到” 的mouseout( 滑鼠移出事件 ), 那麼 "分享到" 這個時候要隱藏, 並不是停止。 為什麼會這樣呢?因為這兩個運動共用了一個計時器, 當滑鼠移動到圖片上, 開啟計時器的時候, 把“分享到”的計時器給停了。 那麼再做多物體運動的時候,我們就要把計時器拆分,每個物件都要有一個計時器,怎麼做呢? 非常簡單,不要定義一個簡單的timer變數,我們只要把timer加在obj物件上,那麼每個物件都有一個timer屬性,就達到計時器的分離效果了

修改之後的完整代碼如下,請自行展開:

View Code

至此,我們就完成了多物體運動與不同樣式的修改

二、讓animate函數支援多個樣式同時改變

比如:

oBox.onmouseover = function(){

animate( this, { "width" : 500, "height" : 400 }, 10 );

}

oBox是一個div元素,animate各參數的意思:

this: 當前div元素

{width : 500, "height" : 400 } : 把寬度變成500, 高度變成400,這兩個樣式要在同一時間完成,

10: 樣式每次在原來的基礎上變化10(如width初始值200--> 210, 220, 230.....)

完整的同時運動變化 代碼:

View Code

請自行展開這段代碼,這段代碼能夠同時運動,但是有一個問題:

div的初始寬度與高度( width : 200, height : 200)

變化步長一樣( 10 )

變化時間一樣( 每30毫秒變化一次 )

目標( width: 500, height : 400 )

你能想到什麼問題嗎?( 兩個人在同一起跑線上,速度一樣, 時間一樣,但是要同時到達不同的目標,一個500, 一個400 )

答案是很明顯的,肯定是目標近的( height : 400 )那個先到達,然後把對象上的計時器關了,另一個目標更遠的( width: 500 )肯定到達不了

你可以在這句代碼下面,輸出當前的值和目標值:

var target = attr[key];

console.log( key, cur, target );

輸出來的結果是:

從上圖可以看出,height已經達到了400px,但是width停在了410px,為什麼不是400px ? 因為width = 400的時候, 就是( cur == 500 ) 相當於( 400 == 500 ) 不成立,所以執行了else語句,width = cur + 10 = 400 + 10 = 410,然後height到達400px停止了計時器,所以width停在了410px.

那麼我們怎麼解決這個問題呢?

其實也好辦,就是height = 400的時候 不要把計時器關了,應該等width = 500的時候再關閉計時器,不就在同一時間,完成了同時到達目標的效果嗎?

修改後的代碼如下:

View Code

聲明一個變數,每次變化完一次( width, height )樣式 把bFlag = true, 只要在for迴圈中有一個沒有到達目標,bFlag的值都是false,這樣就不會關閉計時器。當兩個都到達目標,才關閉計時器.

三、順序運動

如樣式變化,按順序來,不是同時變化, 如:

oBox.onmouseover = function(){

//回呼函數: 把函數當做參數傳遞給另一個函數

animate( this, { 'width' : 500 }, 10, function(){

animate( this, { 'height' : 500 }, 10 );

} );

}

當把width變成500px的時候,如果傳遞了回呼函數, 再接著執行回呼函數裡面的運動

修改後的完整代碼:

View Code

(轉自博客園)

· 什麼?海量IT學習資料白給你都不要?別想了,加群搶:584539956

2017年【中公教育】特別推出就業促進計畫,幫你就業: http://www.ujiuye.com/zt/jycj/?wt.bd=bgz

優就業IT培訓讓你快速成為合格的IT技術型人才,月薪過萬不再是問題:http://www.ujiuye.com/

那麼再做多物體運動的時候,我們就要把計時器拆分,每個物件都要有一個計時器,怎麼做呢? 非常簡單,不要定義一個簡單的timer變數,我們只要把timer加在obj物件上,那麼每個物件都有一個timer屬性,就達到計時器的分離效果了

修改之後的完整代碼如下,請自行展開:

View Code

至此,我們就完成了多物體運動與不同樣式的修改

二、讓animate函數支援多個樣式同時改變

比如:

oBox.onmouseover = function(){

animate( this, { "width" : 500, "height" : 400 }, 10 );

}

oBox是一個div元素,animate各參數的意思:

this: 當前div元素

{width : 500, "height" : 400 } : 把寬度變成500, 高度變成400,這兩個樣式要在同一時間完成,

10: 樣式每次在原來的基礎上變化10(如width初始值200--> 210, 220, 230.....)

完整的同時運動變化 代碼:

View Code

請自行展開這段代碼,這段代碼能夠同時運動,但是有一個問題:

div的初始寬度與高度( width : 200, height : 200)

變化步長一樣( 10 )

變化時間一樣( 每30毫秒變化一次 )

目標( width: 500, height : 400 )

你能想到什麼問題嗎?( 兩個人在同一起跑線上,速度一樣, 時間一樣,但是要同時到達不同的目標,一個500, 一個400 )

答案是很明顯的,肯定是目標近的( height : 400 )那個先到達,然後把對象上的計時器關了,另一個目標更遠的( width: 500 )肯定到達不了

你可以在這句代碼下面,輸出當前的值和目標值:

var target = attr[key];

console.log( key, cur, target );

輸出來的結果是:

從上圖可以看出,height已經達到了400px,但是width停在了410px,為什麼不是400px ? 因為width = 400的時候, 就是( cur == 500 ) 相當於( 400 == 500 ) 不成立,所以執行了else語句,width = cur + 10 = 400 + 10 = 410,然後height到達400px停止了計時器,所以width停在了410px.

那麼我們怎麼解決這個問題呢?

其實也好辦,就是height = 400的時候 不要把計時器關了,應該等width = 500的時候再關閉計時器,不就在同一時間,完成了同時到達目標的效果嗎?

修改後的代碼如下:

View Code

聲明一個變數,每次變化完一次( width, height )樣式 把bFlag = true, 只要在for迴圈中有一個沒有到達目標,bFlag的值都是false,這樣就不會關閉計時器。當兩個都到達目標,才關閉計時器.

三、順序運動

如樣式變化,按順序來,不是同時變化, 如:

oBox.onmouseover = function(){

//回呼函數: 把函數當做參數傳遞給另一個函數

animate( this, { 'width' : 500 }, 10, function(){

animate( this, { 'height' : 500 }, 10 );

} );

}

當把width變成500px的時候,如果傳遞了回呼函數, 再接著執行回呼函數裡面的運動

修改後的完整代碼:

View Code

(轉自博客園)

· 什麼?海量IT學習資料白給你都不要?別想了,加群搶:584539956

2017年【中公教育】特別推出就業促進計畫,幫你就業: http://www.ujiuye.com/zt/jycj/?wt.bd=bgz

優就業IT培訓讓你快速成為合格的IT技術型人才,月薪過萬不再是問題:http://www.ujiuye.com/

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示