2011-04-29 25 views
5

我有一個正在開發的Web應用程序,我試圖讓CTRL + S和COMMAND + S成爲保存的快捷鍵。我看過http://www.openjs.com/scripts/events/keyboard_shortcuts/,它沒有正確捕獲「元」鍵。如何在jQuery中捕獲COMMAND + S?

有什麼建議嗎?

+0

它不捕獲元密鑰,以它不會在所有檢測到它(即,沒有關鍵事件),或者它不會像控制鍵那樣將其識別爲修飾鍵? – cpburnz 2011-04-29 16:04:14

+0

根本沒有檢測到 – Shamoon 2011-04-29 16:31:41

回答

5

最近編輯:請在downvoting這個響應之前,請記住,這是一個非常舊的響應(2011),並沒有更新。顯然現在有更好的反應(如the one by lapin),但這並不意味着我的無效。可以使用jquery hotkeys

編輯:There's a newer version on github,你可以使用 '元' 修改搶命令+:

$(document).bind('keydown', 'meta+s', myaction.save); 

EDIT2:您還可以使用Mousetrap庫/供應商,這是jQuery的自由。

下載最新版本,並修改它按照本附件的變化:http://code.google.com/p/js-hotkeys/issues/detail?id=26

你只需要添加三行:

在行188 aprox的。 (下ctrl = event.ctrlKey,)補充一點:

cmd = event.metaKey && !ctrl, 

然後,添加一個否定的,如果在線203 aprox的。 (if(!shift && !ctrl && !alt){):

if(!shift && !ctrl && !alt && !cmd){ 

最後,if(shift) modif += 'shift+';下補充一點:當您創建

if(cmd) modif += 'command+'; 

現在結合command+whatever它會抓住它:

$(document).bind('keydown', 'command+s', myaction.save); 

在這裏你可以搶最新當前版本(0.7.9)修改:

/* 
(c) Copyrights 2007 - 2008 

Original idea by by Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/ 

jQuery Plugin by Tzury Bar Yochay 
[email protected] 
http://evalinux.wordpress.com 
http://facebook.com/profile.php?id=513676303 

Project's sites: 
http://code.google.com/p/js-hotkeys/ 
http://github.com/tzuryby/hotkeys/tree/master 

License: same as jQuery license. 

USAGE: 
    // simple usage 
    $(document).bind('keydown', 'Ctrl+c', function(){ alert('copy anyone?');}); 

    // special options such as disableInIput 
    $(document).bind('keydown', {combi:'Ctrl+x', disableInInput: true} , function() {}); 

Note: 
    This plugin wraps the following jQuery methods: $.fn.find, $.fn.bind and $.fn.unbind 
*/ 

(function (jQuery){ 
    // keep reference to the original $.fn.bind, $.fn.unbind and $.fn.find 
    jQuery.fn.__bind__ = jQuery.fn.bind; 
    jQuery.fn.__unbind__ = jQuery.fn.unbind; 
    jQuery.fn.__find__ = jQuery.fn.find; 

    var hotkeys = { 
     version: '0.7.9', 
     override: /keypress|keydown|keyup/g, 
     triggersMap: {}, 

     specialKeys: { 27: 'esc', 9: 'tab', 32:'space', 13: 'return', 8:'backspace', 145: 'scroll', 
      20: 'capslock', 144: 'numlock', 19:'pause', 45:'insert', 36:'home', 46:'del', 
      35:'end', 33: 'pageup', 34:'pagedown', 37:'left', 38:'up', 39:'right',40:'down', 
      109: '-', 
      112:'f1',113:'f2', 114:'f3', 115:'f4', 116:'f5', 117:'f6', 118:'f7', 119:'f8', 
      120:'f9', 121:'f10', 122:'f11', 123:'f12', 191: '/'}, 

     shiftNums: { "`":"~", "1":"!", "2":"@", "3":"#", "4":"$", "5":"%", "6":"^", "7":"&", 
      "8":"*", "9":"(", "0":")", "-":"_", "=":"+", ";":":", "'":"\"", ",":"<", 
      ".":">", "/":"?", "\\":"|" }, 

     newTrigger: function (type, combi, callback) { 
      // i.e. {'keyup': {'ctrl': {cb: callback, disableInInput: false}}} 
      var result = {}; 
      result[type] = {}; 
      result[type][combi] = {cb: callback, disableInInput: false}; 
      return result; 
     } 
    }; 
    // add firefox num pad char codes 
    //if (jQuery.browser.mozilla){ 
    // add num pad char codes 
    hotkeys.specialKeys = jQuery.extend(hotkeys.specialKeys, { 96: '0', 97:'1', 98: '2', 99: 
     '3', 100: '4', 101: '5', 102: '6', 103: '7', 104: '8', 105: '9', 106: '*', 
     107: '+', 109: '-', 110: '.', 111 : '/' 
     }); 
    //} 

    // a wrapper around of $.fn.find 
    // see more at: http://groups.google.com/group/jquery-en/browse_thread/thread/18f9825e8d22f18d 
    jQuery.fn.find = function(selector) { 
     this.query = selector; 
     return jQuery.fn.__find__.apply(this, arguments); 
    }; 

    jQuery.fn.unbind = function (type, combi, fn){ 
     if (jQuery.isFunction(combi)){ 
      fn = combi; 
      combi = null; 
     } 
     if (combi && typeof combi === 'string'){ 
      var selectorId = ((this.prevObject && this.prevObject.query) || (this[0].id && this[0].id) || this[0]).toString(); 
      var hkTypes = type.split(' '); 
      for (var x=0; x<hkTypes.length; x++){ 
       delete hotkeys.triggersMap[selectorId][hkTypes[x]][combi]; 
      } 
     } 
     // call jQuery original unbind 
     return this.__unbind__(type, fn); 
    }; 

    jQuery.fn.bind = function(type, data, fn){ 
     // grab keyup,keydown,keypress 
     var handle = type.match(hotkeys.override); 

     if (jQuery.isFunction(data) || !handle){ 
      // call jQuery.bind only 
      return this.__bind__(type, data, fn); 
     } 
     else{ 
      // split the job 
      var result = null,    
      // pass the rest to the original $.fn.bind 
      pass2jq = jQuery.trim(type.replace(hotkeys.override, '')); 

      // see if there are other types, pass them to the original $.fn.bind 
      if (pass2jq){ 
       result = this.__bind__(pass2jq, data, fn); 
      }    

      if (typeof data === "string"){ 
       data = {'combi': data}; 
      } 
      if(data.combi){ 
       for (var x=0; x < handle.length; x++){ 
        var eventType = handle[x]; 
        var combi = data.combi.toLowerCase(), 
         trigger = hotkeys.newTrigger(eventType, combi, fn), 
         selectorId = ((this.prevObject && this.prevObject.query) || (this[0].id && this[0].id) || this[0]).toString(); 

        //trigger[eventType][combi].propagate = data.propagate; 
        trigger[eventType][combi].disableInInput = data.disableInInput; 

        // first time selector is bounded 
        if (!hotkeys.triggersMap[selectorId]) { 
         hotkeys.triggersMap[selectorId] = trigger; 
        } 
        // first time selector is bounded with this type 
        else if (!hotkeys.triggersMap[selectorId][eventType]) { 
         hotkeys.triggersMap[selectorId][eventType] = trigger[eventType]; 
        } 
        // make trigger point as array so more than one handler can be bound 
        var mapPoint = hotkeys.triggersMap[selectorId][eventType][combi]; 
        if (!mapPoint){ 
         hotkeys.triggersMap[selectorId][eventType][combi] = [trigger[eventType][combi]]; 
        } 
        else if (mapPoint.constructor !== Array){ 
         hotkeys.triggersMap[selectorId][eventType][combi] = [mapPoint]; 
        } 
        else { 
         hotkeys.triggersMap[selectorId][eventType][combi][mapPoint.length] = trigger[eventType][combi]; 
        } 

        // add attribute and call $.event.add per matched element 
        this.each(function(){ 
         // jQuery wrapper for the current element 
         var jqElem = jQuery(this); 

         // element already associated with another collection 
         if (jqElem.attr('hkId') && jqElem.attr('hkId') !== selectorId){ 
          selectorId = jqElem.attr('hkId') + ";" + selectorId; 
         } 
         jqElem.attr('hkId', selectorId); 
        }); 
        result = this.__bind__(handle.join(' '), data, hotkeys.handler) 
       } 
      } 
      return result; 
     } 
    }; 
    // work-around for opera and safari where (sometimes) the target is the element which was last 
    // clicked with the mouse and not the document event it would make sense to get the document 
    hotkeys.findElement = function (elem){ 
     if (!jQuery(elem).attr('hkId')){ 
      if (jQuery.browser.opera || jQuery.browser.safari){ 
       while (!jQuery(elem).attr('hkId') && elem.parentNode){ 
        elem = elem.parentNode; 
       } 
      } 
     } 
     return elem; 
    }; 
    // the event handler 
    hotkeys.handler = function(event) { 
     var target = hotkeys.findElement(event.currentTarget), 
      jTarget = jQuery(target), 
      ids = jTarget.attr('hkId'); 

     if(ids){ 
      ids = ids.split(';'); 
      var code = event.which, 
       type = event.type, 
       special = hotkeys.specialKeys[code], 
       // prevent f5 overlapping with 't' (or f4 with 's', etc.) 
       character = !special && String.fromCharCode(code).toLowerCase(), 
       shift = event.shiftKey, 
       ctrl = event.ctrlKey,    
       // patch for jquery 1.2.5 && 1.2.6 see more at: 
       // http://groups.google.com/group/jquery-en/browse_thread/thread/83e10b3bb1f1c32b 
       cmd = event.metaKey && !ctrl, 
       alt = event.altKey || event.originalEvent.altKey, 
       mapPoint = null; 

      for (var x=0; x < ids.length; x++){ 
       if (hotkeys.triggersMap[ids[x]][type]){ 
        mapPoint = hotkeys.triggersMap[ids[x]][type]; 
        break; 
       } 
      } 

      //find by: id.type.combi.options    
      if (mapPoint){ 
       var trigger; 
       // event type is associated with the hkId 
       if(!shift && !ctrl && !alt && !cmd) { // No Modifiers 
        trigger = mapPoint[special] || (character && mapPoint[character]); 
       } 
       else{ 
        // check combinations (alt|ctrl|shift+anything) 
        var modif = ''; 
        if(alt) modif +='alt+'; 
        if(ctrl) modif+= 'ctrl+'; 
        if(shift) modif += 'shift+'; 
        if(cmd) modif += 'command+'; 
        // modifiers + special keys or modifiers + character or modifiers + shift character or just shift character 
        trigger = mapPoint[modif+special]; 
        if (!trigger){ 
         if (character){ 
          trigger = mapPoint[modif+character] 
           || mapPoint[modif+hotkeys.shiftNums[character]] 
           // '$' can be triggered as 'Shift+4' or 'Shift+$' or just '$' 
           || (modif === 'shift+' && mapPoint[hotkeys.shiftNums[character]]); 
         } 
        } 
       } 
       if (trigger){ 
        var result = false; 
        for (var x=0; x < trigger.length; x++){ 
         if(trigger[x].disableInInput){ 
          // double check event.currentTarget and event.target 
          var elem = jQuery(event.target); 
          if (jTarget.is("input") || jTarget.is("textarea") || jTarget.is("select") 
           || elem.is("input") || elem.is("textarea") || elem.is("select")) { 
           return true; 
          } 
         }      
         // call the registered callback function 
         result = result || trigger[x].cb.apply(this, [event]); 
        } 
        return result; 
       } 
      } 
     } 
    }; 
    // place it under window so it can be extended and overridden by others 
    window.hotkeys = hotkeys; 
    return jQuery; 
})(jQuery); 
0

這又是一個簡單的解決方案(?):

$("#YourElementID").keydown(function (e) { 
    if (e.metaKey == true) { 
     alert('meta key yo!'); 
    } 
}); 
0

考慮使用Mousetrap。 (github

我知道這個問題是2歲,回答谷歌。

17

對於那些誰來到一個輕量級的和直接的方式,把工作而無需額外的插件來完成:

$(window).keydown(function (e){ 
    if ((e.metaKey || e.ctrlKey) && e.keyCode == 83) { /*ctrl+s or command+s*/ 
     yourFunction(); 
     e.preventDefault(); 
     return false; 
    } 
}); 
相關問題