顯示廣告
隱藏 ✕
※ 本文為 Knuckles 轉寄自 ptt.cc 更新時間: 2012-02-14 10:12:48
看板 Web_Design
作者 TonyQ (沉默是金)
標題 [心得]從 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
Finding Elements Top and Left Using JavaScript « Vishal Astik Recently, I was trying to create orkut like interface, where user can click on image and upload files using IFrame, so it gave ajax like user experience. For this I used javascript to find top... ...
 
        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(緩和方式,目前預設是'linear' 線性法 ,另有 '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/discuss@jquery.com/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           
www7寫真集
貼圖區,嘟嘟貼圖區,杜蕾斯貼圖區,百分百貼圖區,熊貓貼圖區,皮卡丘貼圖區,jp 貼圖區,漫畫貼圖區,666 貼圖區,只有貼圖區,杜雷斯免費影片貼圖區,貼圖片區,一葉情貼圖片區,kiss911貼圖片區, 貼圖片語法,百分百貼圖片區,貼圖片區5278,美女貼圖片,一葉晴貼圖片,色貼圖片,百分百貼圖片,貼圖片,kiss911貼圖片區,一葉情貼圖片區,貼圖片區5278,嘟嘟貼圖片區,百分百貼圖片區, 布蘭妮貼圖片區,ㄧ葉晴貼圖片區,天下貼圖片區,taiwan kiss911貼圖片區,免費貼圖片區,貼圖片區,視訊聊天交友網511,視訊聊天網sosing,聊天交友網ensshop,哪裡有免費avi影片觀看 ...
 

---
重新修整一些我覺得極度不通暢的文句 , 跟放上我忘記放的兩個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:網路斷線推  XD1F 08/12 12:38
gpmm:push2F 08/12 12:48
ateclean:推3F 08/12 13:21
chrisQQ:推,終於逃出舊的慢網路…4F 08/12 13:22
dspswen:推 !5F 08/12 13:33
※ 編輯: TonyQ           來自: 220.128.219.202      (08/12 13:58)
edl2000:推啊~~~js 製做電動好了 XD6F 08/12 14:12
ateclean:前面不是有個JS的馬力歐7F 08/12 14:53
edl2000:有啊 我知道那個, 沒有人寫新的8F 08/12 15:28
TonyQ:感謝樓上幾位熟面孔的捧場 XD9F 08/12 16:47
appleboy46:推  大推 太用心了10F 08/12 21:50
mlwmlw:推@_@11F 08/13 01:55
TonyQ:那個 由於這兩天要準備講稿 , 加上公司繁忙 ,休稿兩天..XD12F 08/13 08:22
ot32em:pushpushpushpushpushpush!!LA13F 08/13 09:52
TonyQ:結果網路碰到技師搞不定的狀況 , 看來最近帶賽...orz14F 08/13 12:52
TonyQ:看來我跟家裡現有的網路的確有某種斬不斷的羈絆 ... =.=a
ateclean:......剪不斷,16F 08/13 16:59
TonyQ:網路目前總算好了 =.=a  還在準備coscup 200817F 08/14 15:12
TonyQ:話說為了coscup2008 我發響了另一隻 jq plug-in, 之後拿來
TonyQ:當例子解釋plug-in的撰寫吧 :)
TonyQ:                    *發想
Kenqr:推!21F 08/14 21:47
Kenqr:不過demo我都連不上耶
TonyQ:這兩天新申辦的seednet網路不太穩 , 再等等orz23F 08/15 02:11
TonyQ:我有一種我要富監了的感覺 orz
yws:我還以為要畫火之國=_=的標誌25F 08/27 19:17
//修正一個錯字
※ 編輯: TonyQ           來自: 221.169.78.140       (12/01 05:03)
※ 編輯: TonyQ           來自: 61.224.239.208       (12/15 23:53)
TonyQ:修正連結26F 12/15 23:53

--
※ 看板: JavaScript 文章推薦值: 0 目前人氣: 0 累積人氣: 699 
作者 TonyQ 的最新發文:
點此顯示更多發文記錄
分享網址: 複製 已複製
guest
x)推文 r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇