我正在尝试编写一个Javascript / jQuery函数,它会自动将键盘快捷键绑定到我的网页。我想到的方法如下:
非常基本的算法,或者我认为...... 问题即将来临......
例如,我可以输入以下内容:
<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>
以上代码将生成以下键盘快捷键: Ctrl + S 和 Ctrl + Shift + < KBD>取值
当按下这些键时,将为相关的html元素触发click
事件......
如上所述,这里的算法非常简单,但是,像往常一样,在尝试编写时会出现问题。
我无法看到在自动绑定事件时我将如何知道要侦听的键码(e.which
)。
例如:
使用上面的HTML和以下的jQuery,我们可以到目前为止(忽略像正则表达式这样的东西):
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){
}
});
}
正如你从上面所看到的,代码很长,但我根本看不到另一种编写方式...除了可能有一些整齐的数组在这里和那里,但即便如此嵌套如果声明几乎是必要的不是吗?
排除代码非常不整洁且可能写得更好/更好的事实(如果您对此有意见请提供),我的实际问题是参考以下行:
keys.indexOf(charCodeAt(e.which))==-1
这是一种在所有浏览器中从字符代码中检索字符的可靠方法吗?如果没有,有没有更好的方法呢?
任何对其余代码有任何意见的人,请发帖,都希望得到一些反馈。
答案 0 :(得分:1)
当我开始这个时,我并不打算改写整个事情。但我做了,你可以看到它在this jsfiddle工作。
该技术是查找所有目标元素并构建每个映射到哪些键组合的列表。我们将这些存储在数组keybindings
中,每当有人按下某个键时,我们会查看整个列表以查找匹配项。如果我们找到一个,我们会在元素上触发click事件。
我使用keydown
代替keypress
,因为您实际上已经获得了修饰符信息。我还改进了类字符串解析,但我可以肯定它可以做得更清洁。
这是JS代码。
var keybindings = [];
$('[class*="key-"]').each(function (idx, val) {
var keyspec = {
which: 0,
altKey: false,
shiftKey: false,
ctrlKey: false,
element: val
};
var keystring = $(val).attr('class').toLowerCase();
var match = /key-\S+/.exec(keystring);
var parts = match.toString().split('-');
keyspec.which = parts[ parts.length-1 ].toUpperCase().charCodeAt(0);
for (var jdx in parts) {
if (parts[jdx] == 'alt') keyspec.altKey = true;
else if (parts[jdx] == 'shift') keyspec.shiftKey = true;
else if (parts[jdx] == 'ctrl') keyspec.ctrlKey = true;
}
keybindings.push( keyspec );
});
$(document).keydown( function(evt) {
$.each(keybindings, function(idx, oneBind) {
if (evt.which == oneBind.which
&& evt.altKey == oneBind.altKey
&& evt.shiftKey == oneBind.shiftKey
&& evt.ctrlKey == oneBind.ctrlKey)
$(oneBind.element).click();
});
});
当然,现在我发现可能有一个jquery插件,我们可以使用它。