I am trying to write a Javascript/jQuery function that will automatically bind keyboard shortcuts to my webpage. The method I have in mind is something like the following:
- Loop through all elements with a class beginning with 'key-'
- For each of these elements, retrieve the key combinations from the class, e.g. 'key-ctrl-s' will return Ctrl+S
- Bind the event for the combination of these particular keys to the document
Pretty basic algorithm, or so I thought... issue coming...
So for example, I can enter the following:
<a href="javascript:void(0)" class="some_other_class ctrl+s">Save</a>
<a href="javascript:void(0)" class="ctrl+shift+s">Save As</a>
The above code will generate the following keyboard shortcuts: Ctrl+S and Ctrl+Shift+S
And when these keys are pressed, the click
event will be triggered for the relevant html element...
The Issue
As stated above, the algorithm here is pretty darn simple, however, as usual, the problem comes when trying to write it.
I cannot see how I am going to know which keycode (e.which
) to listen for when automatically binding the event.
For example:
Using the above HTML and the following jQuery, we can get thus far (ignore things like the regex):
function keyboardShortcuts(){
// Loop through all elements with a class containing 'key-'
$("[class*='key-']").each(function(){
// Using a regular expression here, separate the class into individual keys
// whilst ignoring other classes and the 'key-' prefix
var keys = $(this).attr('class').match(/REGEX HERE/);
// THIS IS WHERE THE CODE GETS A LITTLE MESSY
// I AM VERY UNSURE ABOUT THE FOLLOWING
// Define all special characters and set them to false
var ctrl = false, alt = false, shift = false;
// First test for special characters
// Test for ctrl key
if(keys.indexOf('ctrl')!=-1){
ctrl = true;
// Remove ctrl from the keys array
keys.splice(keys.indexOf('ctrl'),1)
}
// Test for alt key
if(keys.indexOf('alt')!=-1){
alt = true;
// Remove alt from the keys array
keys.splice(keys.indexOf('alt'),1)
}
// Test for shift key
if(keys.indexOf('shift')!=-1){
shift = true;
// Remove shift from the keys array
keys.splice(keys.indexOf('shift'),1)
}
// Determine special characters to test for
if(ctrl&&alt&&shift){
// Bind the keypress event to the document
$(document).keypress(function(e) {
if((e.ctrlKey||e.metaKey)&&e.altKey&&shiftKey) {
var continue = true;
// Test for other characters in keys array
for(var i=0;i<keys.length;i++){
// THIS IS WHAT I AM REALLY UNSURE ABOUT
if(keys.indexOf(charCodeAt(e.which))==-1){
// Correct key was not pressed so do not continue
continue = false;
}
}
if(continue){
e.preventDefault();
// Proceed to triggering the click event
// No more help needed from here...
}
}
return true;
});
}else if(ctrl&&alt){
}else if(ctrl&&shift){
}else if(shift&&alt){
}else if(ctrl){
}else if(alt){
}else if(shift){
}
});
}
As you can see from the above, the code is quite long winded, but I simply cannot see another way of writing it... Other than maybe a few tidy ups with arrays here and there, but even so the nested if statements are pretty much a necessity aren't they?
Finally, My Question
Excluding the fact that the code is pretty untidy and could probably be written a little/a lot better (if you do have views on this please provide them), my actual question is in reference to the line that reads:
keys.indexOf(charCodeAt(e.which))==-1
Is this a reliable method of retrieving the character from the character code across all browsers? If not, is there a better way to do it?
Anybody that has any opinions on the rest of the code, please post, would love to have some feedback.