1. 程式人生 > >JavaScript之滑鼠滾動事件

JavaScript之滑鼠滾動事件

本文地址:http://blog.163.com/jinlu_hz/blog/static/113830152201122911356714/
原文地址:http://adomas.org/javascript-mouse-wheel/
原文作者:unknown

最近正在做評論模組的image LazyLoad(圖片資源延遲載入/按需載入),其中涉及到一些mouse scroll操作。老外的Mouse wheel programming in JavaScript一文,對我很有價值。

——以下為翻譯——

本文有些資訊可能已經過時,但是大部分知識點仍舊有用。

Web應用日新月異,也越來越接近於桌面應用。功能上越來越強,比如drag&drop(拖拽),autocompletition(自動完成/自動補全)等等。在AJAX的配合下,這些應用都易於實現。

本文要說的並不是AJAX技術,而是關於相對簡單的使用者輸入手段——滑鼠滾輪。目前已經很難找到不帶滾輪的滑鼠了,大多數使用者會使用滾輪用來滾動瀏覽器、縮放頁面/照片之類的操作。Web應用在這個領域卻鮮有建樹。本文將提供一些基於滑鼠滾輪的javascript事件和相關的處理手段。


Annotated code 帶註釋的程式碼

下面是一段帶註釋的javascript程式碼,闡述滑鼠滾動事件背後的一些原理。//此處不準備對程式碼註釋進行翻譯,檢視原始碼

  1. /** 
  2.  * This is high-level function. 
  3.  * It must react to delta being more/less than zero. 
  4.  */
  5. function handle(delta) {  
  6.         if (delta < 0)  
  7.         ...;  
  8.         else
  9.         ...;  
  10. }  
  11. /**  
  12.  * Event handler for mouse wheel event.
     
  13.  */
  14. function wheel(event){  
  15.     var delta = 0;  
  16.     if (!event) /* For IE. */
  17.         event = window.event;  
  18.     if (event.wheelDelta) { /* IE/Opera. */
  19.         delta = event.wheelDelta / 120;  
  20.         /**  
  21.          * In Opera 9, delta differs in sign as compared to IE. 
  22.          */
  23.         if (window.opera)   
  24.             delta = -delta;  
  25.     }  
  26.     else
  27.         if (event.detail) {  
  28.         /** Mozilla case. */
  29.         /** 
  30.          * In Mozilla, sign of delta is different than in IE. 
  31.          * Also, delta is multiple of 3. 
  32.          */
  33.             delta = -event.detail / 3;  
  34.         }  
  35.     /**  
  36.      * If delta is nonzero, handle it. 
  37.      * Basically, delta is now positive if wheel was scrolled up, 
  38.      * and negative, if wheel was scrolled down. 
  39.      */
  40.     if (delta)   
  41.         handle(delta);  
  42.     /**  
  43.      * Prevent default actions caused by mouse wheel. 
  44.      * That might be ugly, but we handle scrolls somehow 
  45.      * anyway, so don't bother here.. 
  46.      */
  47.     if (event.preventDefault)   
  48.         event.preventDefault();  
  49.     event.returnValue = false;  
  50. }  
  51. /**  
  52.  * Initialization code. 
  53.  * If you use your own event management code, change it as required. 
  54.  */
  55. if (window.addEventListener)   
  56.     /** DOMMouseScroll is for mozilla. */
  57.     window.addEventListener('DOMMouseScroll', wheel, false);  
  58. /** IE/Opera. */
  59. window.onmousewheel = document.onmousewheel = wheel; 


Handler function 事件處理函式


程式碼中的"handle"是使用者的自定義函式,其中帶了一個引數為delta。由Deltas pictured. Negative means down, positive up.於瀏覽器平臺的差異性,我們只能夠捕捉到滾動的差值(deltas),這個值是滾輪的變化值。

通常,你只能獲取到delta的正值與負值,如左圖所示。

如果delta是正值,滾動向前滾動,反之則為向後滾動。在許多應用中,向上滾動就是頁面向上滾動。

你可能很疑惑,delta的實際值到底會是什麼。實際上,上述程式碼其實是被調整過的,使得99%的情況下獲取到的值要麼-1要麼就是+1。即時如此,如果在firefox下迅速滾動,會出現±3的情況。Digg上有人提出14的delta值,Geoffrey Kruse在他的pc上甚至得到了76的值。當然了,這也取決於滑鼠敏感度的設定。firefox有一些微妙的現象:如果快速滾動的同時點選右鍵(原文 scrolling the wheel fast and then push the right mouse button for the menu),會報出例如30的delta值。//不明白作者是如何觸發這個操作的

Robert Gerlach在Safari下做了一些測試:”只是滾動一圈的話,值為+-0.1,如果滾動地稍微快點的話(多滾動幾圈),這個值也會變大。 這是因為Mac OS下有滑鼠滾輪加速功能。滾動一次,瀏覽器滾動1畫素,滾動3次,瀏覽器卻滾動30畫素”。同時他也對Camino(基於Gecko的核心引擎)進行研究:“與Safari相似(+- 0.3 to +-Infinity),雖然使用了與firefox相同的核心引擎,但結果這個delta值卻只在+-2.666666裡浮動,無論滾動速度如何。”

在此可以看一下測試頁面A測試頁面B


Compatability 相容性

//作者在此感謝了許多人,不作翻譯

Usability 可用性

Few “don't”s——幾個不要
  • 不要使用滾動進行一些不符合常理的操作,使用者已經習慣用滾輪來作頁面滾動之類的操作了。一些map應用使用滾輪進行縮放,這個操作符合使用者的預期,大膽使用即可。
  • 不要強迫使用者依賴滾輪進行操作。//作者的意思應該提供一種可替換方案,使得在滾輪操作無效的情況下,應用程式仍舊可用
  • 儘量避免全域性滾動條,這些滾動條可能會給使用者在進行滾動時帶來一些困惑。

Real world examples 應用例項

Google Maps利用滾輪進行zoom in/out。
ACME MapperGoogle Maps的增強版//在chrome10下滾動無效
ImageFlow by Finn Rudolph

——翻譯結束——
2011-03-29 11:38:51