Personal tools
You are here: Home ブログ hamabe コマンド入力を実装しよう
« December 2010 »
Su Mo Tu We Th Fr Sa
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
Recent comments
Re:コマンド入力を実装しよう inoue 2007-08-14
 
Document Actions

コマンド入力を実装しよう

[NS] お知らせ:「コナミコマンド」を実装しました. に感動してしまった。

さっそく自分でもJavaScriptでの実装を試みたところ、以外と使えそうなので公開。

これは何?

  • 任意の文字列(コマンド)を入力した後に実行する関数を簡単に設定するものです
  • サンプル.をご覧ください、解説も一緒です(2007/08/12 00:50追記: IEでエラーが起きていたので修正。自爆コマンドでちゃんと致命的エラーが起きるようJavaScriptエラーを修正しました)

使用例

本体:

var KONAMI = function() {
var command_list = [];
var disabled = false;
var permit_key = ' 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
var func_key = {
8: 'back', 9: 'tab', 13: 'enter', 16: 'shift', 17: 'ctrl', 18: 'alt',
27: 'esc', 33: 'pageup', 34: 'pagedown', 35: 'end', 36: 'home',
37: 'left', 38: 'up', 39: 'right', 40: 'down', 46: 'delete'
};

var make_key = function(key) {
if (!key) return ['up','up','down','down','left','right','left','right','b','a'];
if (typeof(key) == 'string') key = key.split(',');
var temp = [];
for (var i = 0, len = key.length; i < len; i++) temp = temp.concat(parse(key[i]));
return temp;
};

var parse = function(key) {
for (var i in func_key) if (key == func_key[i]) return [key];
var arr_char = key.split('');
for (var i = 0, len = arr_char.length; i < len; i++) {
if (permit_key.indexOf(arr_char[i]) == -1) arr_char[i] = '*';
}
return arr_char;
};

var kc2char = function(kc) {
if (kc >= 48 && kc <= 57) return String.fromCharCode(kc);
if (kc >= 96 && kc <= 105) return String.fromCharCode(kc-48);
if (kc >= 65 && kc <= 90) return String.fromCharCode(kc+32);
if (!!func_key[kc]) return func_key[kc];
return (kc == 32) ? ' ' : '*';
};

var check_key = function(evt) {
if (disabled) return;
if(/input|textarea/i.test((evt.target||evt.srcElement).tagName)) return;

var c = kc2char(evt.keyCode);
if (c.length == 1 && evt.shiftKey) c = c.toUpperCase();

for (var i = 0, len = command_list.length; i < len; i++) {
var command = command_list[i];
if (!command.cache) command.cache = [].concat(command.key);

if (command.cache[0] == '*' || command.cache[0] == c) {
command.cache.shift();
if (command.cache.length == 0) {
command.action();
command.cache = [].concat(command.key);
}
} else if (c == 'shift' || c == 'ctrl' || c == 'alt') {
continue;
} else {
command.cache = [].concat(command.key);
if (command.cache[0] == c) command.cache.shift();
}
}
};

if (document.addEventListener) { document.addEventListener('keyup', check_key, true); }
else if (document.attachEvent) {
document.attachEvent('onkeyup', check_key);
var unload = function(){ document.detachEvent('onkeyup', check_key); window.detachEvent('onunload', this); };
window.attachEvent('onunload', unload);
}


return {
command: function(action, key) { command_list.push({ action:action, key:make_key(key) }); },
disabled: function() { disabled = true; },
enabled: function() { disabled = false; }
};
}();

以下のように隠しコマンドを設定します

  • KONAMI.command(アクション, コマンド);

使用例:

KONAMI.command(function(){ window.open('mailto:hoge@fuga') }, 'mail to hoge');
KONAMI.command(bookmarklet_1, 'book,enter,1');

その他ポイント

  • いくつコマンドを登録してもイベント登録はひとつだけ
  • keydownでなくkeyupにイベント登録している。keydownだとキーダウン中に別のキーのkeydownイベントが拾えない。『キーアップ中』なんてものはないのでkeyupイベントはかぶらない。今回のような長文のコマンド入力を間違いなく拾うにはkeyupの方がよい(ただしCtrlやAltとの合わせ押し判定の精度は落ちる)
  • 最近流行のアニメーションだとかスケスケだとか。嫌いな人のために、そういったリッチ化はコナミコマンドで行おう
  • 自爆コマンドをもっと広めたい
Category(s)
JavaScript
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/hamabe/30b330de30f35165529b30925b9f88c5305730883046/tbping

Re:コマンド入力を実装しよう

Posted by inoue at 2007-08-14 11:39
次のマルスケでは、パワーアップコマンドを発行するとProjectAになるとか。
Add comment

You can add a comment by filling out the form below. Plain text formatting.

(Required)
(Required)
(Required)
(Required)
(Required)
This helps us prevent automated spamming.
Captcha Image


Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.