2012-01-07 76 views
2
function Keymap(bindings) { 
    this.map = {}; // Define the key identifier->handler map 
    if (bindings) { // Copy initial bindings into it 
     for(name in bindings) this.bind(name, bindings[name]); 
    } 
} 

// Bind the specified key identifier to the specified handler function 
Keymap.prototype.bind = function(key, func) { 
    this.map[Keymap.normalize(key)] = func; 
}; 

// Delete the binding for the specified key identifier 
Keymap.prototype.unbind = function(key) { 
    delete this.map[Keymap.normalize(key)]; 
}; 

// Install this Keymap on the specified HTML element 
Keymap.prototype.install = function(element) { 
    // This is the event-handler function 
    var keymap = this; 
    function handler(event) { return keymap.dispatch(event, element); } 

    // Now install it 
    if (element.addEventListener) 
     element.addEventListener("keydown", handler, false); 
    else if (element.attachEvent) 
     element.attachEvent("onkeydown", handler); 
}; 

// This method dispatches key events based on the keymap bindings. 
Keymap.prototype.dispatch = function(event, element) { 
    // We start off with no modifiers and no key name 
    var modifiers = "" 
    var keyname = null; 

    // Build the modifier string in canonical lowercase alphabetical order. 
    if (event.altKey) modifiers += "alt_";  
    if (event.ctrlKey) modifiers += "ctrl_"; 
    if (event.metaKey) modifiers += "meta_"; 
    if (event.shiftKey) modifiers += "shift_"; 

    // The keyname is easy if the DOM Level 3 key property is implemented: 
    if (event.key) keyname = event.key; 
    // Use the keyIdentifier on Safari and Chrome for function key names 
    else if (event.keyIdentifier && event.keyIdentifier.substring(0,2) !== "U+") 
     keyname = event.keyIdentifier; 
    // Otherwise, use the keyCode property and the code-to-name map below 
    else keyname = Keymap.keyCodeToKeyName[event.keyCode]; 

    // If we couldn't figure out a key name, just return and ignore the event. 
    if (!keyname) return; 

    // The canonical key id is modifiers plus lowercase key name 
    var keyid = modifiers + keyname.toLowerCase(); 

    // Now see if the key identifier is bound to anything 
    var handler = this.map[keyid]; 

    if (handler) { // If there is a handler for this key, handle it 
     // Invoke the handler function 
     var retval = handler.call(element, event, keyid); 

     // If the handler returns false, cancel default and prevent bubbling 
     if (retval === false) { 
      if (event.stopPropagation) event.stopPropagation(); // DOM model 
      else event.cancelBubble = true;      // IE model 
      if (event.preventDefault) event.preventDefault(); // DOM 
      else event.returnValue = false;      // IE 
     } 

     // Return whatever the handler returned 
     return retval; 
    } 
}; 

// Utility function to convert a key identifier to canonical form. 
// On non-Macintosh hardware, we could map "meta" to "ctrl" here, so that 
// Meta-C would be "Command-C" on the Mac and "Ctrl-C" everywhere else. 
Keymap.normalize = function(keyid) { 
    keyid = keyid.toLowerCase();   // Everything lowercase 
    var words = keyid.split(/\s+|[\-+_]/); // Split modifiers from name 
    var keyname = words.pop();    // keyname is the last word 
    keyname = Keymap.aliases[keyname] || keyname; // Is it an alias? 
    words.sort();       // Sort remaining modifiers 
    words.push(keyname);     // Add the normalized name back 
    return words.join("_");    // Concatenate them all 
}; 

Keymap.aliases = {  // Map common key aliases to their "official" 
    "escape":"esc",  // key names used by DOM Level 3 and by 
    "delete":"del",  // the key code to key name map below. 
    "return":"enter",  // Both keys and values must be lowercase here. 
    "ctrl":"control", 
    "space":"spacebar", 
    "ins":"insert" 
}; 

// The legacy keyCode property of the keydown event object is not standardized 
// But the following values seem to work for most browsers and OSes. 
Keymap.keyCodeToKeyName = { 
    // Keys with words or arrows on them 
    8:"Backspace", 9:"Tab", 13:"Enter", 16:"Shift", 17:"Control", 18:"Alt", 
    19:"Pause", 20:"CapsLock", 27:"Esc", 32:"Spacebar", 33:"PageUp", 
    34:"PageDown", 35:"End", 36:"Home", 37:"Left", 38:"Up", 39:"Right", 
    40:"Down", 45:"Insert", 46:"Del", 

    // Number keys on main keyboard (not keypad) 
    48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9", 

    // Letter keys. Note that we don't distinguish upper and lower case 
    65:"A", 66:"B", 67:"C", 68:"D", 69:"E", 70:"F", 71:"G", 72:"H", 73:"I", 
    74:"J", 75:"K", 76:"L", 77:"M", 78:"N", 79:"O", 80:"P", 81:"Q", 82:"R", 
    83:"S", 84:"T", 85:"U", 86:"V", 87:"W", 88:"X", 89:"Y", 90:"Z", 

    // Keypad numbers and punctuation keys. (Opera does not support these.) 
    96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9", 
    106:"Multiply", 107:"Add", 109:"Subtract", 110:"Decimal", 111:"Divide", 

    // Function keys 
    112:"F1", 113:"F2", 114:"F3", 115:"F4", 116:"F5", 117:"F6", 
    118:"F7", 119:"F8", 120:"F9", 121:"F10", 122:"F11", 123:"F12", 
    124:"F13", 125:"F14", 126:"F15", 127:"F16", 128:"F17", 129:"F18", 
    130:"F19", 131:"F20", 132:"F21", 133:"F22", 134:"F23", 135:"F24", 

    // Punctuation keys that don't require holding down Shift 
    // Hyphen is nonportable: FF returns same code as Subtract 
    59:";", 61:"=", 186:";", 187:"=", // Firefox and Opera return 59,61 
    188:",", 190:".", 191:"/", 192:"`", 219:"[", 220:"\\", 221:"]", 222:"'" 
}; 

JavaScript權威指南:第六屆Keymap.js你能告訴我一些關於Keymap.js的例子嗎?(權威指南)?

Keymap.js:綁定的關鍵事件處理函數。

該模塊定義了一個Keymap類。這個類的一個實例代表一個 關鍵標識符(定義如下)到處理函數的映射。 Keymap 可以安裝在HTML元素上以處理keydown事件。當發生這樣的事件時,鍵映射使用其映射來調用適當的處理程序。

當您創建Keymap時,您可以傳遞代表 Keymap的初始綁定集的JavaScript對象。該對象 的屬性名稱是關鍵標識符,屬性值是處理函數。 在創建鍵映射後,您可以通過將密鑰 標識符和處理函數傳遞給bind()方法來添加新綁定。您可以通過將密鑰標識符傳遞給unbind()方法來刪除綁定 。

要使用鍵盤映射,請調用其install()方法,並傳遞HTML元素 (如文檔對象)。 install()將onkeydown事件處理程序添加到指定對象的 。當這個處理程序被調用時,它確定按鍵的標識符 ,並調用綁定到該鍵標識符的處理函數,如果有的話, 。一個鍵盤映射可以安裝在多個 一個HTML元素上。

密鑰標識符

甲密鑰標識符是一個鍵加 被同時按住任何修改鍵不區分大小寫的字符串表示。密鑰名稱通常是 密鑰上的(未轉換的)文本。合法的關鍵名稱包括「A」,「7」, 「F2」,「PageUp」,「Left」,「Backspace」和「Esc」。

請參閱本模塊中的Keymap.keyCodeToKeyName對象以獲取名稱列表。 這些是由DOM Level 3標準定義的名稱的子集,並且該類將在實現時使用事件對象的關鍵屬性。

密鑰標識符還可以包括修飾符密鑰前綴。這些前綴是 Alt,Ctrl,Meta和Shift。它們不區分大小寫,並且必須使用空格或下劃線將 與密鑰名稱和相互間隔開, 連字符或+分開。例如:「SHIFT + A」,「Alt_F2」,「meta-v」和「ctrl alt left」。 在Mac上,Meta是Command鍵,Alt是Option鍵。某些瀏覽器 將Windows鍵映射到Meta修飾符。

處理函數

處理程序被調用作爲在其 安裝鍵映射的文檔或文檔元素的方法和傳遞兩個參數: 1)的事件對象爲keydown事件 2)密鑰標識符被按下的鍵 處理程序返回值成爲keydown處理程序的返回值。 如果處理函數返回false,則鍵映射將停止冒泡,並且取消與keydown事件關聯的任何默認操作。

...

回答

3

摘要代碼:

  • KeyMap一個新實例通過new關鍵字創建。
    可選地,有可能通過含有鍵映射的對象,以預先結合:

    { 
        "key-combi1": func1, //key-combi such as alt+a, ctrl+c, shift+s 
        "key-combi2": func2, 
        .... 
        "key-combin": funcn //<-- Last property should not end with a comma 
    } 
    
  • 創建一個新的實例(var keymap = new Keymap();)之後,可以使用以下的方法(聽取在邏輯時間順序) :

    1. bind - 添加附加鍵結合
      keymap.bind("key-combi", function);
    2. unbind - 刪除鍵綁定
      keymap.unbind("key-combi");
    3. install - 將鍵映射到元件(綁定到​​事件)
      keymap.install(element);

實例

用這個方法最簡單的方法如下所示:

var keymap = new Keymap;      // Create a new instance of Keymap 
keymap.bind("ctrl_a", function(event, keyid) { // Bind key combi: ctrl+a 
    alert("Key pressed down! KeyId: " + keyid) 
}); 
keymap.install(document.body);     // Attach keymap to <body> 

的另一種方式,以相同的結果:

var keymap = new Keymap({      // Create a new instance of Keymap 
    "ctrl_a": function(event, keyid) {   // Bind key combi: ctrl+a 
     alert("Key pressed down! KeyId: " + keyid) 
    } 
}); 
keymap.install(document.body);     // Attach keymap to <body> 
+0

:謝謝,我試試吧! – Terry 2012-01-07 10:36:19

+0

但我不能讓它工作!!你能告訴我! – Terry 2012-01-07 10:58:16

+0

> _>什麼是「不工作」?你能在[小提琴](http://jsfiddle.net)中展示你的嘗試嗎? – 2012-01-07 11:07:55

相關問題