2010-11-02 5 views
7

Tôi tò mò về cách tôi, với đoạn mã jQuery plugin sau đây được viết ở cuối câu hỏi này, có thể thực hiện các combo chính. Làm thế nào nó hoạt động cho đến nay là nó cho phép người dùng để tạo ra các lệnh chốt chỉ đơn giản bằng cách thực hiện một jQuery bình thường như cú pháp và cung cấp một sự kiện cho các lệnh quan trọng, như vậy:Thực hiện các combo chính với jQuery/JavaScript

$(window).jkey('a',function(){ 
    alert('you pressed the a key!'); 
}); 

hoặc

$(window).jkey('b c d',function(){ 
    alert('you pressed either the b, c, or d key!'); 
}); 

và cuối cùng những gì tôi muốn là khả năng để làm, nhưng không thể tìm ra:

$(window).jkey('alt+n',function(){ 
    alert('you pressed alt+n!'); 
}); 

tôi biết làm thế nào để làm điều này bên ngoài của các plugin (trên KeyUp thiết lập một var sai và trên KeyDown thiết lập var đúng và kiểm tra nếu var là đúng khi bạn bấm phím khác), nhưng tôi không biết làm thế nào để làm điều này khi bạn không biết những gì các phím sẽ được ép và bao nhiêu. Làm cách nào để thêm hỗ trợ này? Tôi muốn có thể cho phép họ làm những việc như alt+shift+a hoặc a+s+d+f nếu họ muốn. Tôi chỉ không thể có được đầu của tôi xung quanh làm thế nào để thực hiện điều này. Ý tưởng nào?

Tôi sẽ phát hành ứng dụng này dưới dạng plugin nguồn mở và tôi muốn cung cấp cho bất kỳ ai cho tôi quyền, làm việc, trả lời một số tín dụng trên bài đăng trên blog và trong mã là bản thân. Cảm ơn trước!

(function($) { 
    $.fn.jkey = function(keyCombo,callback) { 
    if(keyCombo.indexOf(' ') > -1){ //If multiple keys are selected 
     var keySplit = keyCombo.split(' '); 
    } 
    else{ //Else just store this single key 
     var keySplit = [keyCombo]; 
    } 
    for(x in keySplit){ //For each key in the array... 

     if(keySplit[x].indexOf('+') > -1){ 
      //Key selection by user is a key combo... what now? 
     } 
     else{ 
      //Otherwise, it's just a normal, single key command 
     } 

     switch(keySplit[x]){ 
      case 'a': 
       keySplit[x] = 65; 
       break; 
      case 'b': 
       keySplit[x] = 66; 
       break; 
      case 'c': 
       keySplit[x] = 67; 
       break; 
      //And so on for all the rest of the keys 
     } 
    } 
    return this.each(function() { 
     $this = $(this); 
     $this.keydown(function(e){ 
      if($.inArray(e.keyCode, keySplit) > -1){ //If the key the user pressed is matched with any key the developer set a key code with... 
       if(typeof callback == 'function'){ //and they provided a callback function 
        callback(); //trigger call back and... 
        e.preventDefault(); //cancel the normal 
       } 
      } 
     }); 
    }); 
    } 
})(jQuery); 

Trả lời

2

Đây là những gì tôi nghĩ ra. Về cơ bản những gì tôi đã làm được tạo ra một đối tượng JSON lưu trữ tất cả các mã khóa. Sau đó tôi thay thế tất cả các khóa được cung cấp bằng các mã. Nếu các phím đang sử dụng dấu '+' để tạo một tổ hợp phím, thì tôi sẽ tạo một mảng các mã trong số đó.

Sau đó chúng tôi tạo một mảng khác lưu trữ tất cả các phím đang được nhấn (keyDown thêm mục, keyUp sẽ xóa nó). Trên keyDown, chúng tôi kiểm tra xem đó là một lệnh hoặc tổ hợp phím.Nếu đó là một combo, chúng tôi kiểm tra nó với tất cả các phím bấm hiện đang hoạt động. Nếu tất cả chúng khớp nhau, chúng tôi thực thi cuộc gọi lại.

Điều này sẽ hoạt động với bất kỳ số lượng combo chính nào. Chỉ có thời gian tôi thấy rằng nó không được làm việc là khi bạn sử dụng 'alert()' để hiển thị một tin nhắn trên tổ hợp phím bởi vì nó sẽ không còn loại bỏ các mục từ mảng báo chí phím hoạt động.

(function($) { 
    $.fn.jkey = function(keyCombo,callback) { 

    // Save the key codes to JSON object 
    var keyCodes = { 
     'a' : 65, 
     'b' : 66, 
     'c' : 67, 
     'alt' : 18 
    }; 

    var x = ''; 
    var y = ''; 

    if(keyCombo.indexOf(' ') > -1){ //If multiple keys are selected 
     var keySplit = keyCombo.split(' '); 
    } 
    else{ //Else just store this single key 
     var keySplit = [keyCombo]; 
    } 

    for(x in keySplit){ //For each key in the array... 

     if(keySplit[x].indexOf('+') > -1){ 
     //Key selection by user is a key combo 
     // Create a combo array and split the key combo 
     var combo = Array(); 
     var comboSplit = keySplit[x].split('+'); 

     // Save the key codes for each element in the key combo 
     for(y in comboSplit){ 
      combo[y] = keyCodes[ comboSplit[y] ]; 
     } 

     keySplit[x] = combo; 

     } else { 
     //Otherwise, it's just a normal, single key command 
     keySplit[x] = keyCodes[ keySplit[x] ]; 
     } 

    } 

    return this.each(function() { 
     $this = $(this); 

     // Create active keys array 
     // This array will store all the keys that are currently being pressed 
     var activeKeys = Array(); 

     $this.keydown(function(e){ 

      // Save the current key press 
      activeKeys[ e.keyCode ] = e.keyCode; 

      if($.inArray(e.keyCode, keySplit) > -1){ // If the key the user pressed is matched with any key the developer set a key code with... 

      if(typeof callback == 'function'){ //and they provided a callback function 
       callback(); //trigger call back and... 
       e.preventDefault(); //cancel the normal 
      } 

      } else { // Else, the key did not match which means it's either a key combo or just dosn't exist 

      // Check if the individual items in the key combo match what was pressed 
      for(x in keySplit){ 
       if($.inArray(e.keyCode, keySplit[x]) > -1){ 

       // Initiate the active variable 
       var active = 'unchecked'; 

       // All the individual keys in the combo with the keys that are currently being pressed 
       for(y in keySplit[x]) { 
        if(active != false) { 
        if($.inArray(keySplit[x][y], activeKeys) > -1){ 
         active = true; 
        } else { 
         active = false; 
        } 
        } 
       } 

       // If all the keys in the combo are being pressed, active will equal true 
       if(active === true){ 
        if(typeof callback == 'function'){ //and they provided a callback function 
        callback(); //trigger call back and... 
        e.preventDefault(); //cancel the normal 
        } 
       } 
       } 
      } 

      } // end of if in array 

     }).keyup(function(e) { 
      // Remove the current key press 
      activeKeys[ e.keyCode ] = ''; 
     }); 

    }); 

    } 
})(jQuery); 
+0

Bạn đang xác định 'x' trong phạm vi toàn cục. –

+0

Tôi nghĩ rằng vấn đề phạm vi có thể được cố định bằng cách xác định x và y như thế này: var x = ''; var y = ''; ? – sebnitu

+0

Hoặc tốt hơn, chúng ta có thể định nghĩa chúng bằng cách thêm var vào câu lệnh for? cho (var x trong keySplit) {... – sebnitu

0

Đây chỉ là ảnh chụp trong bóng tối nhưng có thể nó sẽ giúp bạn đi đúng hướng.

Nếu có thể để chức năng đó nhận ra giá trị thập lục phân cho khóa mà bạn đã nhập thay vì phím chữ (ví dụ 0x6E cho chữ 'n'), bạn có thể lấy được thông tin "alt + n" hex và có hàm nhìn ra cho giá trị đó.

+0

AWH, thú vị, ốm nhìn vào nó. Cảm ơn! Ngoài ra, bạn có một tài liệu tham khảo về làm thế nào để chuyển đổi chúng thông qua JS? Tôi chưa có Googled ... –

5

Sử dụng nhấn phím thay vì khóa/mở khóa vì hai sau không chính xác bảo vệ mã phím (reference, xem đoạn cuối). Bạn có thể tham khảo các altKeyctrlKeyshiftKey tính boolean của đối tượng sự kiện trong trường hợp này ...

$(document).keypress(function(e) { 
    var key = String.fromCharCode(e.which); 
    var alt = e.altKey; 
    var ctrl = e.ctrlKey 
    var shift = e.shiftKey; 
    alert("Key:" + key + "\nAlt:" + alt + "\nCtrl:" + ctrl + "\nShift:" + shift); 
}); 

Ngoài ra, bạn có thể sử dụng String.fromCharCode để dịch mã chìa khóa để một lá thư thực tế.

Bạn không thể bẫy nhiều khóa ngoài các kết hợp bằng Ctrl, Alt và Shift. Bạn chỉ đơn giản là không thể làm điều đó trong một sự kiện duy nhất. Vì vậy, hãy ném ý tưởng a+s+d+f ra ngoài cửa sổ.

Lưu ý: Rõ ràng có một số tổ hợp phím nhất định được trình duyệt sử dụng. Ví dụ: Alt + F thường hiển thị menu Tệp trong Windows. Ctrl + N thường khởi chạy một cửa sổ/tab mới. Làm không cố gắng ghi đè bất kỳ kết hợp nào trong số những kết hợp này.

Đây là số live demo cho niềm vui thử nghiệm của bạn.

+0

Vì vậy, làm thế nào để tôi tích hợp điều đó và làm cách nào để tích hợp nó để bất kỳ tổ hợp phím nào sẽ hoạt động, ví dụ: shift + alt + f + d + s nếu họ muốn. Giống như tôi đã nói, điều này là dành cho tôi, nhưng nó cũng sẽ được phát hành công khai, vì vậy tôi vẫn cần phải cho phép sau đó ghi đè lên các giá trị mặc định của trình duyệt như ctrl + t mặc dù tôi sẽ không bao giờ được :) –

+0

Rất tiếc, sau đó, shift + alt + f, làm thế nào để tôi tích hợp vào plugin, xin lỗi –

+0

Bạn không thể bẫy nhiều khóa, vì vậy hãy quên nó đi. Sự kiện này được kích hoạt một lần cho mỗi lần nhấn phím. Các chỉ báo boolean chỉ cho bạn biết có hay không Ctrl, Alt hoặc Shift được giữ khi phím được nhấn. Theo mặc định của trình duyệt ghi đè, không, KHÔNG và ** KHÔNG! ** –

-1

Nếu bạn đang tìm kiếm cái gì đó sẽ cho phép người dùng dễ dàng nhập và xác định combo key sử dụng một hộp đầu vào đơn giản, tôi đã viết một plugin nào đó cho bạn: http://suan.github.com/jquery-keycombinator/