看板 Ajax 關於我們 聯絡資訊
※ [本文轉錄自 Web_Design 看板] 作者: TonyQ (沉默是金) 看板: Web_Design 標題: [心得]從 js 到 jQuery 之六:五光四色的特效世界 時間: Tue Aug 12 11:45:59 2008 本章一開始 , 我們先來看看一個小弟精心準備的小小demo吧. http://tonyq.org/jqtalk/jq6_effectDemo.html ──────────────────────────────── 呵 , 一個小小的demo , 帶下我們今天的主題 , 與其說是特效 , 其實指的是 animation , 動態效果. 其實說到這一章 , 算是會讓我比較熱血沸騰 , 擔心會寫到失控的一章 , 當初學 javascript 很大的一個因素是因為這個 ,從第一篇到第五篇, 我們不斷的強調 js 的用途主要在於修改頁面上的屬性 , 而用得最淋漓盡 致的應用 , 就在動態效果. @demo頁的code好像有一點複雜 , 而且好像沒看到 jQuery呢? 我之所以要特地在最前面放一個傳統js寫出來的demo頁 , 主要是想強調 的是 jQuery 並不能平白生出各種效果 , 也是透過一些搭配來產生這些效果. 比方說在 #18dWSoRf (web_design) 一文中我就用js展示能做到opacity fade 跟color fade的模擬代碼 , 當然並沒有把所有情境考慮進去 , 但是只要把握 本章我們提的工具 , 你就不會迷失在各種令人目眩神迷的特效裡面. js底下沒有新把戲 , 只是看你有沒有想到而已 . 這章算是傳統 js 跟 jQuery差距比較小的一章 , 因為觀念是 jQuery無法簡化 的 , 只有學習才能真的把非常複雜的事情簡化. 當然如果你不是立志要當一個開發效果的coder , 而只是想套用別人的效果 , 本章可以讓你對於套用這些效果的「副作用」更了解一些. @demo 是怎麼做的? 我以demo中有用到的一些技巧先行介紹 , 首先各位讀者應該有發現 , 他是一個行為一個行為依序進行的 , 在這裡我們是透過計時器來處理 . 雖然說計時器是被我包裝成我比較習慣使用的模樣 , 不過我還是得介紹原型. 傳統 js 提供兩種計時器 , 其不僅僅是能夠提供我們計算時間而已 , 同時他也是屬於非同步(Asynchronous)運算的 , 對 multi-thread有了解的版友們可以把它想像成另一個thread. @計時器 這兩個分別為 Timeout / Interval , 分別有對應的使用跟移除的function, 為 window.setTimeout(expr,time) window.setInterval(expr,time) window.clearTimeout(id) window.clearInterval(id) 先談談用法 , expr 可以是javascript的字串 , 像是 "alert('hi');" 它會用eval的方式來呼叫,也可以是函數 , 像是 function(){alert('hi'); 而time則是距離下一次執行的間隔時間(以ms為單位 , 1秒=1000ms) 不管是timeout或interval , 他們第一次都會是在計時器時間到時執行, 但 timeout 跟 interal最大的差異就是 , 前者呼叫時只會執行一次, 後者則是每隔指定時間就會呼叫expr這個函數,直到你把它clear掉. 每次當你呼叫 setTimeout或 setInterval時 , 他都會回傳一個數字 , 那個數字就是所謂的timerId , 用來識別多個timer中是哪一個, 你需要透過timerId來clear掉對應的 Timeout 或 Interval. @timer這麼猛 , 那我可以什麼都用timeout做非同步處理嗎? 由於多一個計時器本身就是不小的成本 , 建議是僅在必要時使用. @計時器的時間準確嗎? 他本身難免還是會有一些誤差 , 不過我個人經驗是在100~200ms左右而已 , 需要較高精確度時 , 時間區間要設小一點 , 然後透過紀錄date的時間差來算 目前差距時間,這樣會更準確一點. @還有其他的東西嗎? 目前扣掉最基本的 show/hide , 你可能會比較想知道怎麼把元素指到指定的 位置,基本上我們也是透過css中的 position:absolute 搭配 left/top移動到 指定的位置 . 當然這樣另一個問題就來了 , 我們常會有一個畫面上的標地物. 比方說以tip效果而言 , mouseover後顯示資料在對應的物品旁邊, 我會需要這個事件對象的座標 , 一般在傳統js我們會用 offsetLeft跟 offsetTop , 不過這兩個dom元件的屬性在ie跟fx解讀下不同 , 前者會解讀成自己跟父元素的left-top差距 , 後者則是在頁面上得left-top , 所以在ie底下要取得 正確的 offsetLeft 要跑一個for loop 往父元素加總. 這其實一直都是許多人所碰到的釘子,因為這也是個常見的需求. 以 jQuery而言 ,用原為 dimension plug-in 的 offset(), 它現已被整合進1.2.6 jQuery Core , 可用來取得left跟top , 就不需要自行維護寫function找左 上 , 寬高則可透過 css取. 傳統作法在這裡我先引用別人的文章來做說明 , 實際代碼可見底下連結. http://0rz.tw/c74xz function GetTopLeft(elm) @我注意到你的圖形是跑圓形的 , 圓形的軌跡怎麼來的? 如果各位讀者有看source的話 , 應該會看到我是用 ( rCosΘ , rSinθ) 的方案 , 並且讓半徑r 成比例縮小來達到螺旋狀的效果 , 對於三角函數還有印象的朋友, 可以看底下這個簡單的示意圖, 回想圓投影的公式,當然這不是這裡的重點 , 就不多做著墨. . - . . r /|. . . . /θ| . .  ̄ ̄ . . . ` 我想表達的是對一個平面物來講 , 他就是只有 x,y座標 , 你必須去計算他每個時間點的每個位置才能做出一連串的軌跡, 這過程中你偶爾會需要一些數學的輔助 , 像是線性遞增的等加級數就是常 用的技巧之一, 相對的 , 算法的優劣也就是決定效果出來好不好的關鍵 . 我們繼續分享一些操作上得基本技巧 , 當你想把一個位置從 0,0 慢慢移動到 50,15 時, 假設設定移動15次時走到 , 那你每次就要走 ((50-0)/15, (15-0)/15) 的長度 , 就可以在次數到達時 , 走到目的地 . 當然如果你想扭扭腰之類的 , 就得去計算各個折點 , 或者仰賴簡諧運動公式. (這邊都還在高中物理/高中數學的範疇 , 想想高中真是學了一堆鬼東西..) 至於立體軌跡 , 可能需要去找一下怎麼把 x,y,z投影到x,y平面的公式. 想把移動軌跡做水平扭曲或垂直扭曲的話 , 旋轉矩陣 會是個好幫手. 好啦 , 我知道不少位讀者現在心理正在哀號這些是什麼鬼東西 , 我只是想提醒大家 , 學習可以簡化問題的難度... 有付出去學習就會有對應的收穫 .. 如果做不到 , 就是要多花時間學 , 而不是說對方就像神一樣平白變魔術 , 仰賴jQuery協助我們做到許多 特效時 , 也可以順便思考它是怎麼做的 , 筆者是一直對於沒把離散跟線代給學好 , 覺得有些遺憾 , 當然本身不是數學相關科系出身 , 所以知道的也不是很多, 對於常常有人在討論數學到底有沒有用的議題 , 我想學習對於簡化事情都是有正面幫助的. 無趣的碎碎念與閒話談的夠多了 , 讓我們進下一個部份吧. @副作用? 像我紅色點的軌跡紀錄中是用多個div 當紀錄點 , 這在本來就很龐大的 網頁的話就可能會造成負擔 , 當然像這種額外插幾個元素進去處理 在各plug-in都是很常見的作法 . 有時候可能一來是需要考慮運算的複雜度 , 二來是要考慮到多個元件 會不會有互相干擾的狀況 , 這些都是需要列入考慮的 . 在底下兩個前提下 , js能透過計算作不少事情. 1.不繪圖: 雖然js可以做到類似點陣繪圖的效果 , 可是效能很差 ,而且又不能存成圖片 , 基本上是接近廢物 , 2.不需要對圖片做特別處理(扭曲翻轉 ) 但是相對的 js 只要一多 , 對瀏覽器來講負擔就很重 , 使用者應該有經驗就是逛網頁逛一逛突然間記憶體用量暴增 , 那通常都是 js 跟 圖片過多且沒有好好的釋放掉所導致的 , 這點在 map 類的網頁特別常見 , firefox以前有一隻叫leak Monitor的 plug-in可以觀察哪些資料沒被釋放掉 , 不過後來一直看到各網站都有, 就乾脆關掉了...有興趣者可參考下方連結. https://addons.mozilla.org/zh-TW/firefox/addon/2490 雖然由一個推廣 js的人來講很奇怪 , 不過請不要覺得 javascript 是萬靈藥, 很多事情不是不存在 ,只是還沒遇上(淚目), 在要考慮到 js solution時 , 記得把對應的 loding風險列入評估. 基本上我會建議不會再用到的物件可以用 [delete]這個關鍵字順手刪掉, 雖然把需要用到的東西順手delete掉的情況也是偶爾會發生 . (攤手) 關於js coding上得一些減輕負擔或增加體驗的經驗 , 有機會再跟大家分享 . @關於 js 我們談的夠多了 , 來點 jQuery吧 基本上在特效這點 jQuery可說沒什麼特別好幫忙的 .(才怪!) 它只是幫你處理許多做動態效果所需要的跨平台支援 , 跟提供了數種基本實用的基本動態實做效果而已嘛...^^ 接下來就來看看兩種最常見的特效 fadeIn跟 slideDown 吧 像是fadeIn/fadeOut/fadeTo (採透明度方案的) , 還有 slideDown / slideUp 這類花俏的彈出彈入 , 幾乎是各家都不會少的. 簡單demo就好 :) http://tonyq.org/jqtalk/jq6_jqEffectsDemo.html @我可以簡單的做到其他的效果嗎? 這裡要特別介紹的是 animate( ) 這個方法 , 他可以讓你提供多個參數, 包括 param duration (經過時間,也可填'fast','slow','normal') easing(緩和方式,目前預設是'inear' 線性法 ,另有 'swing'可選) 還有callback 指的是在animate動作結束後要呼叫的方法. 我想應該看到這裡還有很多人跟我一樣不曉得這能幹麻吧? 他的概念其實很簡單 , 你結果想要達到什麼 , 就寫在 param 裡面 , 過程想要什麼效果 , 就交給 easing決定 . 比方說我現在想從現在的 , 寬度變400px ,高度變200px. 並且希望他在 1.5秒內完成 , 就這樣寫 $("#helloButton").click( function(){ $("#anNode").animate( { width: "400px", height: "200px" } , 1500 ); } ); 簡單示例 http://tonyq.org/jqtalk/jq6_jqAnimateDemo.html 不過比較遺憾的是 animate目前只支援可成為單一數字化的欄位, 比方說border寬度 , height , width , left, top 之類的 像color跟background color 目前都得透過 plug-in做到 . 關於color的相關的mailing 問題 http://www.mail-archive.com/[email protected]/msg17329.html 擴充 animate color的 plug-in http://plugins.jquery.com/project/color 目前試用過 , 至少backgroundColor沒問題 (background不行就是了:P) 加上顏色變換之後的簡單demo http://tonyq.org/jqtalk/jq6_jqAnimateColorDemo.html @還有什麼好東西? 新版目前還支援 queue的效果 , 可以讓你依序執行多個 function , 用這東西寫的話我本來的code就不用寫那麼長了...:P 直接看doc上得demo頁 , 把多個效果組合在一起 . http://docs.jquery.com/Effects/queue @體驗時間 由於這整章幾乎都在體驗時間...這次就先不介紹了 :P (另外是這章的撰寫時間破歷史新高 , 害我打破一天一篇的計畫..) --- 這篇看起來好像寫了很多 , 其實又好像什麼都沒寫 ,真的是學了越多忘了越多 .XD 順便祝賀一下 , 家裏網路終於在請假半天的代價下搞定了 , 希望晚上回來能有比較正常的網路頻寬可以用 ,逛個ptt打個字都要0.5秒 delay 還要寫長文真是太折磨我了些... 如果有錯字或者缺字就是頻寬害的(牽托ing...) 總之 , 第六篇希望給大家有一點驚豔的感覺 , 下一篇我們要回頭講新增/刪除網頁元素 , 一樣會很有趣的 . :) -- What do you want to have ? / What do you have? 從書本中,你可以發現我的各種興趣。 從CD中,你可以瞭解我所喜歡的偶像明星。 或許從文字你很難以瞭解一個人,但從物品可以。 My PPolis , My past. http://ppolis.tw/user/Tony --- 重新修整一些我覺得極度不通暢的文句 , 跟放上我忘記放的兩個sample link. 另摘於下 http://tonyq.org/jqtalk/jq6_jqAnimateDemo.html http://tonyq.org/jqtalk/jq6_jqAnimatecolorDemo.html /*加入color plug-in*/ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 220.132.59.247
JYHuang:網路斷線推 XD08/12 12:38
gpmm:push08/12 12:48
ateclean:推08/12 13:21
chrisQQ:推,終於逃出舊的慢網路…08/12 13:22
dspswen:推 !08/12 13:33
※ 編輯: TonyQ 來自: 220.128.219.202 (08/12 13:58) -- What do you want to have ? / What do you have? 從書本中,你可以發現我的各種興趣。 從CD中,你可以瞭解我所喜歡的偶像明星。 或許從文字你很難以瞭解一個人,但從物品可以。 My PPolis , My past. http://ppolis.tw/user/Tony -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 220.128.219.202
awpadam:推!認真的範例網頁!! 08/12 17:25
ilake:推推推 08/13 07:06
TonyQ:ilake欸 好久不見 , 改天再去你那搶鳥(誤) XD 08/13 11:43
superGA:push 08/13 19:49
kosgroup:推 05/04 02:43
※ 編輯: TonyQ 來自: 61.224.239.208 (12/16 00:00)