スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。



mirrorMan - インクリメンタルサーチ

エクスプローラのフォルダウインドウでファイル名をタイプすると、その文字にマッチするファイルにフォーカスが移ります。「m」と入力するとファイル名の頭に「m」がついているファイル、続けて「irr」と入力すると「mirr」がついているファイルという具合に、連続したキー入力でフォーカスが移動していくのを目で確認しながら、目的のファイルを探し出すことができます。
FFFTPでサーバの大量ファイルを探すときにはおなじみの機能で、Vistaでも検索ウインドウやスタートメニューのファイル名を指定して実行などで取り入れられています。たとえばエクセルを使うなら、ウインドウズキーを押してexcelと入力すれば最近使ったエクセルファイルがすぱっと一覧で表示されるので、UIとしては最短距離ではないでしょうか。PCのアイドル時にひたすらカリカリとインデックスを作成しているだけあります。評判が悪いというか地に堕ちたVistaですが、検索機能は職場でも使いたいです。元々Mac派でWindows95のときは憎しみすら覚えたクチなんですが、ごく短い期間ですがMSで働いたこともあって、今はWindowsに同情する側です。

ソースの該当部分ですが、まず、
document.body.onkeydown = handleKeydown;
onkeydownをhandleKeydownにオーバーライドします。参照ではないので、()は付けません。


function handleKeydown(){
var ky = event.keyCode;
var shKy = event.shiftKey, ctKy = event.ctrlKey, alKy = event.altKey;
if((!ctKy)&&(!shKy)&&(!alKy))
if(((ky>=48)&&(ky<=57)) || ((ky>=65)&&(ky<=90)) || ((ky>=97)&&(ky<=111)))
return selItmByKeyDown(ky);
}
Shiftキーや、Ctrlキー、Altキーの押下状態は、IEの場合トップレベルのeventオブジェクトにあります。
これらのキーが押されている場合をまず除外します。さらに、0-9、A-Z、a-zの範囲だった場合に処理を行います(テンキーの0-9は別のkeyCodeですが対応していません)。onkeydownにかぶせる処理はここまでです。

次に画面の動きです。

たとえば「qwef」と入力すると、

1.3秒間、このようにキー入力をプールした状態を表示します。1.3秒間は入力追加とし、最初に入力したキーからそれ以上経過するとクリアします。そして、ここに表示している文字列をもとにファイル名の検索を行います。インクリメンタルサーチ入力の閾値が1.3秒で、それ以降は新しい入力だというわけです。短いと入力し切れないし、長いと次の新しい入力を待ってイライラ、とあんばいがムズカシスところです。


「b」をタイプしたタイミングで「bac」フォルダにフォーカスします。続けて「a」をタイプしても、まだ文字はマッチしているので1.3秒間以内であればフォーカスは移りません。さらに「k」をタイプして「bak」となれば「bak」フォルダにフォーカスが移ります。


ソースです。
function clearKeyDownPool(){
if(keyDowns.innerText) keyDowns.innerText ="";
}
setTimeout()で1.3秒後に文字列をクリアする処理を関数で用意します。
文字列を表示しているspanタグはid=keyDownsです。

function selItmByKeyDown(k){
k = String.fromCharCode(k).toLowerCase();
if(k != keyDowns.innerText){
setTimeout('clearKeyDownPool()',1300);
k = keyDowns.innerText += k;
}
var elms = document.getElementsByTagName('PRE');
var t, i = cntSelItmId();
for(; i<elms.length; i++){
t = elms[i].innerText;
if((t.indexOf(k) == 0)||(t.indexOf(k.toUpperCase()) == 0)){
if((i == cntSelItmId())&&(k.length < 2)) continue;
selItmLR.innerText = /Lft/.test(elms[i].id) ? 0 : 2;
cntSelItmId(elms[i].id.replace(/...(\d+)/,'$1'));
selItm(elms[i]);
break;
}
}
}
1行目でkeyCodeを文字にしています。
2~5行目では、同じ文字の入力だった場合をはじいています。なぜなら、たとえばa、a、aと入力された場合は、1.3秒なんて待たずに「a~」という名前のファイルに次々とフォーカスが移るべきだからです。それに、頭から同じ文字が続くファイル名なんてほとんどみたことがありません。
画面上では、4行目でinnerText値の更新を処理し、;でコミットしたタイミングで追加入力している文字列が表示されるはずですね。少なくとも、次のfor文の中でinnerTextを取得する段階ではそうなっていないと動作しません。
6行目以降は、ファイルの一覧から一致する名前を探し出す処理です。
htmlの要素の値として持てる文字列と、ファイル名として持てる文字列とは制限に違いがあるので、ファイル名の表示はpreタグに入れてあります。それをgetElementsByTagName()でノードオブジェクトを取得し、画面に表示されているファイルのすべての名前にアクセスできるようにします。
cntSelItmId()は現在フォーカスされているアイテムをid属性値からたどってファイルオブジェクトを取得するためのインデックス値を格納するための処理で、上の画像の数字部分に表示しています。常に画面に表示しておくことで、グローバル変数としてどこからでもアクセスできること、フォーカスがいまどこにあるのかを見れることが目的です。詳細はここでは省略します。
selItm()は、ファイル名を反転表示させてフォーカスを示す処理です。実際はIEのフォーカスではなくて、textRangeオブジェクトのselect()ですが、これも詳細は省略します。
スポンサーサイト



comment

Secret

while(aho.atEndofStream)

笹部 政宏
笹部 政宏
mail




フリーソフツ
Category
はてブ
Monthly Archive
New Entry
New Comment
New Trackback
RSS
Copyright © Kittens flewby me All Rights Reserved.

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。