我编译了代码(发布在下面):
var keys = [];
var key1="17"; //ctrl
var key2="16"; //shift
var key3="83"; //s
window.addGlobalHotkey = function(callback,keyValues){
if(typeof keyValues === "number")
keyValues = [keyValues];
var fnc = function(cb,val){
return function(e){
keys[e.keyCode] = true;
executeHotkeyTest(cb,val);
};
}(callback,keyValues);
window.addEventListener('keydown',fnc);
return fnc;
};
window.executeHotkeyTest = function(callback,keyValues){
var allKeysValid = true;
for(var i = 0; i < keyValues.length; ++i)
allKeysValid = allKeysValid && keys[keyValues[i]];
if(allKeysValid)
callback();
};
window.addEventListener('keyup',function(e){
keys[e.keyCode] = false;
});
addGlobalHotkey(function(){
var x = getIn("What Task?");
switch(x)
{
case "a":
//...
break;
case "t":
//...
break;
default:
//...;
}
},[key1,key2,key3]);
function getIn(text){
var x = prompt(text);
if (x != null && x != ''){
return x;
}
}
prompt
)switch
或选项)addGlobalHotkey(function(){/PLAY HERE/},[key1,key2,key3]);
所以现在你有了整个背景。它使用GreaseMonkey和TamperMonkey在Firefox,Chrome中运行良好,并且完全符合我的需要。
然而,我注意到在任何给定标签上执行它后,该特定标签开始逐渐变慢,悬挂,延迟涂料,只有解决方案就是关闭它。其他选项卡不受影响,只是您执行时所在的选项卡。所以我担心可能会有内存泄漏,这是我错过的代码中的东西吗?可以以某种方式改进以确保不是这样吗?
另外,我注意到99%以上的时间,它释放键很好,有时你按下键盘上的任意键并执行命令,这表明钩子不正确自行清理,导致任何钥匙陷入困境并处理触发器,即使不是指定的钥匙,我想念的是什么?可以提高稳定性吗?
答案 0 :(得分:2)
你可以做几件事但我没有看到内存泄漏的原因。
我评论过我的编辑。
var keys = [];
// Integers takes less space than strings, and we might as well put it in an array already
var shortcut = [
17, // ctrl
16, // shift
83 // s
];
window.addGlobalHotkey = function(callback, keyValues){
if(typeof keyValues === "number")
keyValues = [keyValues];
// Unfortunately, because you need the cb argument we can't define it outside the addGlobalHotkey method.
var fnc = function(cb, val){
return function(e){
keys[e.keyCode] = true;
executeHotkeyTest(cb, val);
};
}(callback, keyValues);
window.addEventListener('keydown', fnc);
return fnc;
};
window.executeHotkeyTest = function(callback, keyValues) {
var i = keyValues.length;
while(i--) {
// If key is not pressed, we might as well abort
if(!keys[keyValues[i]]) return;
}
callback();
};
window.addEventListener('keyup',function(e) {
// Remove key instead of setting it to false
keys.splice(e.keyCode, 1);
});
addGlobalHotkey(function() {
var x = getIn("What Task?");
// If x is empty there's no point in resuming
if(!x) return;
// If-statements are faster than switches, just saying.
switch(x)
{
case "a":
//...
break;
case "t":
//...
break;
default:
//...;
}
}, shortcut);
function getIn(text){
var x = prompt(text);
// Altered if statement
if(typeof x === 'string' && x.length > 0) return x;
}
最大的潜在泄漏事实是,只要按下更多不同的键,阵列键就会增长。因此.splice()
方法。
我再次审核了您的代码。每当您注册新的热键时,我都会注意到您创建了一个新的onkeydown
侦听器。我已经改变了。请尝试使用以下代码,看看它是否仍然运行缓慢。
/* VARIABLES */
var keysPressed = [];
var hotkeys = [];
/* EVENT LISTENERS */
// Listen for keydown once instead for every hotkey
window.addEventListener('keydown', function(e) {
// A button was pressed
keysPressed[e.keyCode] = true;
checkHotkeys();
}, false);
window.addEventListener('keyup', function(e) {
// Remove key
keysPressed.splice(e.keyCode, 1);
}, false);
/* FUNCTIONS */
function checkHotkeys() {
var i = hotkeys.length;
while(i--) {
executeHotkeyTest(
hotkeys[i].callback,
hotkeys[i].keys
);
}
};
function addGlobalHotkey(callback, keys) {
if(typeof keys === "number")
keys = [keys];
hotkeys.push({
callback: callback,
keys: keys
});
};
function executeHotkeyTest(callback, keys) {
var i = keys.length;
while(i--) {
// If key is not pressed, we might as well abort
if(!keysPressed[keys[i]]) return;
}
callback();
};
function getIn(text){
var x = prompt(text);
// Altered if statement
if(typeof x === 'string' && x.length > 0) return x;
}
/* OTHER */
// Integers takes less space than strings
var shortcut = [
17, // ctrl
16, // shift
83 // s
];
addGlobalHotkey(function() {
var x = getIn("What Task?");
// If-statements are faster than switches, just saying.
switch(x)
{
case "a":
//...
break;
case "t":
//...
break;
default:
//...;
}
}, shortcut);
我发现了这个问题!
所以我们一直使用keycode作为数组的索引 - 一个数字索引。这些不关联。看看下面的例子。
0: 'abc',
1: 'def',
2: 'ghi'
删除1
0: 'abc',
1: 'ghi'
删除2
0: 'abc',
1: 'ghi'
通过将它们转换为字符串,您的数组将成为关联数组,右键将被删除。
// Listen for keydown once instead for every hotkey
window.addEventListener('keydown', function(e) {
// A button was pressed
keysPressed[e.keyCode.toString()] = true;
checkHotkeys();
}, false);
window.addEventListener('keyup', function(e) {
// Remove key
delete keysPressed[e.keyCode.toString()];
}, false);
查看工作演示:http://jsfiddle.net/rQePB/1/