keypressイベントではなくsetIntervalを使って定期的に入力された文字列を読み取り、マッチする候補文字列をリストアップします。
【詳細】
focus時にsetIntervalを仕込みます。blur時、clearIntervalします。
上矢印、下矢印、TAB、ENTERキーのイベントは必要なのでそのままです。
文字列を読み取って候補をリストする処理をsetIntervalで呼び出すことになります。読みやすくするためメソッドにします。
【結論】
意外や意外、簡単に実装できました。相当苦労するんじゃないかとビビッてたんですが。
JavaScriptの経験が浅いのでこの辺の予測が弱いようです。
ディレクトリ構造は変更なしです。
WebContent
- js/prototype.js
- js/my.js
- a.html
- my.css
■my.js
// 外出しです。
var div1 = null;
var cursor_pos = -1;
var element_len = 0;
// cleraIntervalする対象です。
var tid;
// 定期的にテキストボックスをチェックします。
// いちいち再描画されることを避けるため、
// 以前に入力された文字列と等しい場合はスキップする必要があります。
var previousInput = "";
Event.observe(window, 'load', function(event) {
// イベントを登録します。
var keyevent = 'keydown';
if (window.opera || (navigator.userAgent.indexOf('Gecko') >= 0
&& navigator.userAgent.indexOf('KHTML') == -1)) {
keyevent = 'keypress';
}
Event.observe($('hoge'), keyevent, function(event) {
if (event.keyCode == Event.KEY_DOWN) {
if (element_len > cursor_pos) {
cursor_pos++;
}
var hogeTmp = $('div1'+cursor_pos);
initiateListColors();
hogeTmp.style.backgroundColor = '#00FF00';
} else /* elseをつけましたよ */
if (event.keyCode == Event.KEY_UP) {
if (cursor_pos > 0) {
cursor_pos--;
}
var hogeTmp = $('div1'+cursor_pos);
initiateListColors();
hogeTmp.style.backgroundColor = '#00FF00';
} else
if (event.keyCode == Event.KEY_TAB
|| event.keyCode == Event.KEY_RETURN) {
if (cursor_pos >= 0) {
var hogeTmp = $('div1'+cursor_pos);
$('hoge').value = hogeTmp.innerHTML;
}
$('candidate').style.visibility = "hidden";
}
});
// onBlur イベントを登録します。
Event.observe('hoge', 'blur', function(event) {
if (div1) {
// div1がnullでない場合はhiddenにします。
$('candidate').style.visibility = "hidden";
// ポジションを初期化します。
cursor_pos = -1;
}
clearInterval(tid);
});
// onFocus イベントです。
Event.observe('hoge', 'focus', function(event) {
tid=setInterval("listCandidates()",500);
});
});
function initiateListColors() {
var tmpElems = $('candidate').childElements();
for (var j = 0; j < tmpElems.length; j++) {
tmpElems[j].style.backgroundColor = "#FF0000";
}
}
// 外だしにしました。
function listCandidates() {
if (previousInput == $('hoge').value) {
// 入力された文字が変更されていなければ抜けます。
return;
} else {
previousInput = $('hoge').value;
}
// クリアします
$('candidate').innerHTML = "";
$('candidate').style.visibility = "visible";
cursor_pos = -1;
var i;
var size = -1; // <- 当たり前ですが重要です。
var rObj = new RegExp($('hoge').value);
for (i = 0; i < week.length; i++) {
// 入力された文字が一致していた候補を表示します。
var tmpSearch = week[i];
if (tmpSearch.match(rObj) != null) {
size++; // <- iではなくてsizeをincreしながら使います
// 文字列がマッチしていたらappendします。
var tmpId = 'div1'+size;
div1 = new Element('div', {'id' : tmpId });
div1.innerHTML = week[i];
div1.style.backgroundColor = "#FF0000";
div1.style.width = "100px";
$('candidate').appendChild(div1);
Event.observe(tmpId, 'mouseover', function(event) {
this.style.backgroundColor = "#00FF00";
});
Event.observe(tmpId, 'mouseout', function(event) {
this.style.backgroundColor = "#FF0000";
});
Event.observe(tmpId, 'mousedown', function(event) {
$('hoge').value = this.innerHTML;
$('candidate').style.visibility = "hidden";
});
}
}
element_len = size;
}
■a.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-31j">
<script type="text/css" src="my.css"></script>
<!-- 変数をmy.jsより先に読み込む必要があります。 -->
<script type="text/javascript">
var week = new Array("hokkaido","aomori","akita",
"yamagata","miyagi","niigata","fukushima",
"ikkei", "komori", "higata");
</script>
<script type="text/javascript" src="js/prototype.js"></script>
<script type="text/javascript" src="js/my.js"></script>
<title>Ajax tutorial - a</title>
</head>
<body>
<input type="text" id="hoge" name="hoge" />
<div id="candidate"></div>
</body>
</html>
■my.css(結局使わなかった・・・)
@CHARSET "UTF-8";
/* CSSは表示と関係ありません */
#div1 {
visibility:hidden;
}
このシリーズは以上で完了です。
.
0 件のコメント:
コメントを投稿