天天看點

不依賴jQuery也能做好動畫

在開發者社群中有種錯誤的觀念——認為在web中,CSS動畫是唯一高性能的動畫方式。這使很多開發者放棄基于JavaScript的動畫。是以導緻——(1)強制使用大量樣式表來完成複雜的UI互動,(2)不能很好地支援IE8、9,(3)放棄隻有JS才能完成的完美實體運動效果。

事實證明:基于JavaScript的動畫和基于CSS的動畫一樣快,甚至有時更快。CSS動畫通常是和非常慢的jQuery

$.animate()

比較。但是,JavaScript庫如果能避免像jQuery那樣大量的DOM操作,性能就會非常高。這些庫能比jQuery快20倍。

是以,讓我們來打破一些神話,通過一些動畫執行個體,并在此過程中提高自己的設計技巧。

為什麼是JavaScript

CSS動畫能友善地實作漸變效果,也不需要額外地加載庫。但是它很難支援複雜的效果。代碼不易管理、特性不能滿足需求而導緻失敗。

最終CSS動畫無法完成要求。但JavaScript和大多程式設計語言一樣,支援大量的邏輯控制。JavaScript動畫引擎用事實證明了這點,這裡有些小技巧可以參考:

如果你對性能感興趣,可以看看Julian Shapiro 的 “

CSS vs. JS Animation: Which Is Faster?

” 和

Jack Doyle 的 “

Myth Busting: CSS Animations vs. JavaScript

” 。性能的示範可參考 Velocity 的 “

performance pane

” 和 GSAP 的 “

Library Speed Comparison

Velocity 和 GSAP

兩個最流行的JavaScript動畫庫是

Velocity.js

GSAP

。它們都不依賴于jQuery,使得性能提高。

假如你的網站已經用了 jQuery,那就可以像使用 jQuery 一樣使用 Velocity 和 GSAP。例如:

$element.animate({ opacity: 0.5 });

就可以寫成

$element.velocity({ opacity: 0.5 })

如果你沒有使用 jQuery 也能使用這兩個庫。但是不能像綁定一系列動畫到JQ元素上那樣,要把元素傳進動畫函數裡,例如:

/* Working without jQuery */

Velocity(element, { opacity: 0.5 }, 1000); // Velocity

TweenMax.to(element, 1, { opacity: 0.5 }); // GSAP

如上所示,在沒有使用JQ的情況下,Velocity 的用法和JQ一樣,把目标元素寫到第一個參數位置,再把其他參數依次往右寫。

GSAP與此不同,采用的是面向對象的API設計,和靜态方法一樣友善。是以你可以完全掌控整個動畫。

在這兩種情況下,你不再是使用一個jQuery的動畫元素對象,而是一個原始的DOM節點。你可以通過

document.getElementByID

document.getElementsByTagName

document.getElementsByClassName

document.querySelectorAll

(和jQuery的選擇器很類似)。

不使用jQuery

(注:如果你要學習基本的jQuery

$.animate()

的用法,可以參考Velocity文檔開始的幾段)

querySelectorAll是擺脫jQuery的好武器

document.querySelectorAll("body"); // 擷取body元素

document.querySelectorAll(".squares"); // 擷取所有包含square類的元素

document.querySelectorAll("div"); // 擷取所有div

document.querySelectorAll("#main"); // "main"擷取含有id為main的元素

document.querySelectorAll("#main div"); // 擷取#main裡的div

如上面所示,你可以輕松地把CSS選擇器傳給

querySelectorAll

,它會傳回一個包含所有比對元素的數組。是以,你可以這樣做:

/* 擷取所有div */

var divs = document.querySelectorAll("div");

/* 給所有div加上動畫 */

Velocity(divs, { opacity: 0.5 }, 1000); // Velocity

TweenMax.to(divs, 1, { opacity: 0.5 }); // GSAP

我們不再将元素綁定為jQuery對象,那如何一個接一個地實作動畫呢?

$element // jQuery 對象

    .velocity({ opacity: 0.5 }, 1000)

    .velocity({ opacity: 1 }, 1000);

在Velocity裡,你隻需一個接一個調用動畫:

Velocity(element, { opacity: 0.5 }, 1000);

Velocity(element, { opacity: 1 }, 1000);

這種方式沒有性能缺陷。要把做動畫的目标元素用變量存儲起來使用,而不是每次都用querySelectorAll查找一次。

(提示:使用Velocity的包,你可以建立自己的多操作的動畫,并給他們取名字,你就可以像Velocity的第一參數一樣操作它。

點選這裡

檢視更多。)

這種

one-Velocity-call-at-a-time

的方式有個好處:如果你使用promises,那麼Velocity每次調用後會傳回一個可使用的

promise

對象,這非常有用。你可以通過

Jake Archibald的文章

了解更多。

GSAP面對對象的方式允許把動畫排入時間線,友善排程和同步控制。這樣就不局限于一個接一個的連結動畫。你可以嵌套時間表、使動畫重疊等。

var tl = new TimelineMax();

/* GSAP預設使用tweens鍊,但你可以在時間線上指定精确的插入點,包括相對偏移 */

tl

  .to(element, 1, { opacity: 0.5 })

  .to(element, 1, { opacity: 1 });

繼續閱讀