顯示廣告
隱藏 ✕
※ 本文為 Knuckles 轉寄自 ptt.cc 更新時間: 2012-02-14 10:09:43
看板 Web_Design
作者 TonyQ (沉默是金)
標題 [心得]從 js 到 jQuery 之三:可怕的事件叢林
時間 Sat Aug  9 02:57:09 2008




        感謝前兩篇各位版友的不吝支持 , 接下來要推出第三篇 ,
        還請各位版友多多指教、討論。︿︿


        希望看完這篇 , 你們能了解網頁上得事件有哪些 ,
        以及為什麼事件在跨平台這件事情上是件很棘手的事情.

        ────────────────────────────────

        繼「無所遁形的selector」一文體驗到的強大 jquery selector ,
        暫且讓我們放下 jquery 物件的各種attr css 的屬性不談 ,

        先來談談我們之前所講過 , javascript最重要的觸發點:事件.

        ────────────────────────────────

      @事件,網頁樂團中的鼓手。

        事件掌握著網頁上得所有節奏 , 就算你完全不使用任何javascript ,
        當你瀏覽網頁 , 就起碼有讀取(onload)跟離開(onunload)正在默默進行 ,

        當然要奏出美妙樂曲 , 還得要整個樂團的配合 ,  javascript 就是這整個
        事件中的指揮家 , 指揮著各項元素各司其職, 演出一場美妙的狂想曲.


        事實上 , 當我看到這個網頁時  , 才深深地體會js 的可能性.
        http://www.nihilogic.dk/labs/mario/mario_small_music.htm
Play juegos de Super Mario Bros Online game (small, with music) - Nihilogic JavaScript games: Play the first level of Super Mario Bros. 14KB JavaScript in your browser. ...
 


      @事件聽起來是個通用名詞,那我們有哪些事件呢?

        事件一定綁定(binding)著一個 dom物件, 這是先介紹selector的理由。

        基本上大部分事件是所有元素通用的 , 比方說onmouseover , onclick等 ,
        也有些事件只有某些物件會使用 , 像是 onchange , onsubmit 等 .



        底下簡單列表 , 將我們今天的各大主角簡單列出來

        on click        物件被按下
        on change       物件內容改變(select,input text等form類型元件專用)
        on mouseover    滑鼠進入dom元件四周的那一剎那觸發
        on mouseout     滑鼠離開元件四周時觸發
        on mousemove    介於over跟out之間的所有移動行為(會頻繁觸發)
        on focus        當元件被點選 或者透過tab鍵取得焦點時觸發
        on load         在網頁最一開始讀取完成時執行 , 常用於body或iframe.
        on keydown      按下鍵盤按鍵時 ,主要用於body跟input text.
        on keyup        放開鍵盤按鍵時

        還有更多其他種類 可見此網頁詳細介紹 ,
        http://stuck.myweb.hinet.net/c/js/js_events.htm


      @這麼多種? 我統統都會用到嗎?

        我自己常用的是前面七個 , 其中又以 click  mouseover mouseout load居多,
        各種事件常見的應用情境跟組合雖然非常有趣 , 但還是先留待以後再做介紹,

        我們這篇接下來要告訴大家的是 , 「什麼是事件」.


      @什麼? 前面的介紹還不夠詳細嗎?

        乍看之下你似乎知道所有事情 , 但繼續耐心看下去 ,
        你會了解前面介紹的只是事件的一半左右而已 ,

        接下來我們要教你的仍然是書上所不常提到 , 但是非常有趣的事情.


      @不是就像click一樣 , 按下去就一個事件嗎?

        沒錯 , 在某些狀況下是這樣 , 你不需要了解任何事件的細節 ,
        就只是在對應的觸發時間點執行js 不需要任何其他資訊 .


        但是當你想在網頁上追蹤你的滑鼠游標時 , 當你想知道你按下的鍵盤按鍵
        究竟是哪一顆按鍵時 ,或者看完mario之後 ,
        你可能會有雄心壯志想做個網頁版的格鬥天王之類的 ,

        那你就需要一些關於事件的資訊.


      @事件紀錄者的歡喜與憂愁

        值得高興的事情是 , 瀏覽器早就幫你想到了這件事情 ,
        於是每個事件必定會伴隨著一個紀錄事件資訊的物件.(底下以event代稱)

        event物件會紀錄是誰觸發了這個事件(srcElement),
        滑鼠游標移到哪,或者keydown按下的按鍵是哪一個(keycode)之類的。


        許多特效諸如tooltip , dragand drop 都是根據這些資訊做出來的 ,
        既然如此 , 那為什麼要說憂愁呢?


        身為一個有志氣的網頁設計師, 你應該會想要至少支援Firefox跟ie雙平台 ,
        或者甚至於像筆者我所在的公司有兩位同事是mac愛好者 , safari 也是我們
        需要考慮的對象.



      @能跨瀏覽器當然好呀 , why not?

        問題在於這些瀏覽器對於事件參數的支援都各有一些不同的解讀 ,
        就以取得 event物件來講好了 , ie 提供 window.event 可取得,
        firefox則需要透過function傳遞參數.


        而且事件提供的內容來講 , 更是各家都有所不同 ,

        像是要透過事件取得被綁定的對象是誰 , ie下是event.target,
        firefox下是 event.srcElement, 諸如此類的 .

        在你撰寫程式碼時需要時時注意,是否需要寫一些 if-else ,
        以達到不同瀏覽器一樣的效果.


      @看起來跨瀏覽器很麻煩...

        沒錯!所以有些人選擇只支援 ie體系 , ie only的是非不是我們所關心的 ,
        我們有更好的選擇!就是選用 jQuery當我們的平台媒介!

        在jQuery底下 , 常見瀏覽器有支援的事件元素 , 全部被整合為同樣的介面,
        而我們所關心的事件物件如何取得 , 則是透過function傳入param的方式.


        有興趣的朋友們可以分別用fx跟ie開這個sample頁 ,
        透過mousemove一窺事件的全貌.

        http://tonyq.org/test/testMousemove.html

        左右皆是將事件內容印出來的結果.

        左邊是jquery element的內容物 , 右邊是當前browser的內容物.
        可以發現fx跟ie底下右邊的資料會有所不同 , 左邊則是一致的.


        在大部分的狀況下 , jQuery 都將 跨平台的問題謹記在心,

        除了部份嚴重issue (ex. ie6 bgirame) 等需特別處理外 ,
        jQuery通常能達到足以令人滿意的跨平台效果.

        (之後應會有機會繼續介紹其他跨平台特性的部份。)


      @一個元素只能綁定一種事件嗎?

        答案當然是否定的 , 比方說我可能會希望 mouseover移動過inputtext,
        時該text自動取得焦點(focus) , text改變時自動做一些檢查(change).

        很多時候我們會用事件去呼叫別的元素執行事件 , 達到連環事件的效果.


      @可以在javascript中綁定事件嗎?


        你可以把 onclick 等參數視為 dom成員中的一種 ,
        賦予其對應的事件成員一個 function 物件.

        比方說 inputNode.onclick=function(){ alert("hi");};

        就是針對inputNode綁定onclick事件.

        但是透過 = 指定的話 , 之前綁訂的事件會被覆蓋 ,
        如果你希望是附加而非覆蓋的話 , 應該要透過 attachEvent的方式進行.

        這裡又有瀏覽器相容性的問題 attachEvent是ie only ,
        addEventListener 則是 firefox有支援的 .


      @天啊怎麼又來了!!難道就沒有跨瀏覽器的好解法?

        現在你知道為什麼我們要特地強調跨瀏覽器平台了吧(聳肩)

        別擔心 , 要綁定幾次都沒問題 , jQuery會幫我們處理好一切的.

        $("#ele").click(function(e){alert("hi");})
                .click(function(e){alert("hi");})
                .click(function(e){alert("hi");})
                .click(function(e){alert("hi");});

        你看 我們這不就綁定了四個事件給ele了嗎?
        (http://tonyq.org/test/testEventBinding.html )


     @咦? $("#ele").click(event).click(event) ...?

        這是jquery的有趣特性之一 , 他幾乎所有成員都會回傳jquery物件本身,
        所以我們可以達成這種稱之為「method chaining」的效果.

        當然你想中規中矩的寫成
        $("#ele").click(function(e){alert("hi");});
        $("#ele").click(function(e){alert("hi");});

        也無妨 , 一切取決於你的習慣.

        當物件被click時  , 會按照綁定的順序依序觸發.
        (當你不想要時 , 可透過  $("#ele").unbind("click") 來解除所有事件.))


     @事件真是複雜 , 還有我應該知道的嗎?

        關於事件其實我們聚焦在基礎資料的介紹 , 因為我們認為
        你早晚會知道 hover事件 = mouseover + mouseout ,

        以及原來想要到處都擺個click+ajax的慾望是如此讓人興奮(害怕).


        但是還有一件事情我們還沒有告訴你 , 那就是事件的相依性.
        在能見到的區域中 , body是所有元素的根源 , 相信你不會否認這句話 ,


        當你在頁面上綁定一個元素, (以下例中的 input button)

        <body >
                <div>
                        <input type="button" value="button" />
                </div>
        </body>

        則當button被click時 , div跟body的onclick也會被觸發.
        因為button實際上也是div的成員 , div也會把它視為一體的觸發

        同樣的理由 , 所以對body也觸發 ,
        有些時候我們會需要用這個trick 實做一些事情.


      @那能不能讓他不要觸發上級的元素呢?

        可以 ,對事件方法 return false ; 告訴他我執行到這裡就結束.
        ex. $("[type=button]").click(function(e){return false;});


        相依性最常見的用途在於檢查表單資料是否正確填寫 ,
        我們可以透過
        $("form").submit(
                function(e){
                     if($("#inputdata").val()=="")  //如果某個input text是空白
                        return false; //我就不submit了
                }
        );


      @體驗時間
        我們今天介紹的是 jquery corner這隻plug-in ,
        可以幫你把區塊式的元件很輕鬆的加上圓角的效果 .

        http://tonyq.org/jqtalk/jq3_jqCorner.html


---
剛剛歷經pcman當掉跟差點睡著 的危機, 總算還是順利寫完了 ,
祝各位版友週末愉快..需要加班的也能早點休息 :)


最後再補一些注意事項 ,

例子大多是針對CLICK寫 , 不過其他的事件其實大同小異,
另外 js 使用過度有害網頁健康 , 請不要真的作成到處都click +ajax,

以及各種酷炫特效不斷充斥 , 大多數狀況下這樣會導致網頁執行起來有笨重的感覺.

--
        What do you want to have ?  / What do you have?            
        從書本中,你可以發現我的各種興趣。
        從CD中,你可以瞭解我所喜歡的偶像明星。

        或許從文字你很難以瞭解一個人,但從物品可以。
        My PPolis , My past. http://ppolis.tw/user/Tony           

--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.132.59.247
※ 編輯: TonyQ           來自: 220.132.59.247       (08/09 03:01)
TonyQ:JQ Corner 官網 http://malsup.com/jquery/corner/1F 08/09 03:07
Allenguy:推2F 08/09 03:55
ot32em:推!3F 08/09 04:39
Kenqr:推!4F 08/09 14:03
TonyQ:我們下一篇要討論的是 attr /css 的getter跟setter5F 08/09 15:30
TonyQ:屬性與樣式-瀏覽器的真正戰場
ateclean:感覺下一篇會很熱血XD7F 08/09 18:03
Ramone:推 !8F 06/18 15:05
※ 編輯: TonyQ           來自: 61.224.239.208       (12/15 23:48)
TonyQ:修正連結9F 12/15 23:48

--
※ 看板: JavaScript 文章推薦值: 0 目前人氣: 0 累積人氣: 1342 
分享網址: 複製 已複製
1樓 時間: 2014-03-26 17:25:45 (台灣)
guest-2b0PzX
  03-26 17:25 TW
guest
x)推文 r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇