肉とビールとパンケーキ by @sotarok

少し大人になった「肉とご飯と甘いもの」

onkeyupのブラウザ別挙動

最近はちょくちょくAjaxとかいじり始めてまして・・・そうなると必然的に苦手なJSも・・・(笑)
まあ、大方の処理は先人の築いた優秀なライブラリにまかせているにしても、イベントハンドラどうする?入力値の監視?とか。

というわけで、イベントハンドラを使って、入力があるごとにその値の整合性をチェックしよう!というスクリプトを書いた。

というのも、Twitterのセッティング画面の「USERNAME」の部分で、キーを打つたびにその名前が使えるかどうかをチェックしてくれていて(Youtubeも最近そうなってた)、これが便利だなーと思ったので。

というわけで、とある検索画面にて、入力値が変更されるごとに(キーを押すごとに)結果一覧が変更されるという便利アイテムを。。*1

<input type="text" id="searchbox" name="searchbox" onkeyup="searchExe();" />
<div id="result"></div>

みたいなカンジにして、searchExe()では

function searchExe() {
    var FormArea = $('searchbox');

    new Ajax.Updater(
        'result',
	'search.php',
	{
            parameters : $H({query:FormArea.value}).toQueryString()
        }
    );
}

みたいな。当たり前のようにprototype.js使ってしまっていますがその辺は許してください。ダッテベンリダシ…

てかJavascriptホント書きなれてないからソースさらすのはずいな。ツッコミがあればお願いしたい。。



ところが、ここで問題が発生した。

この、onkeyup、TwitterYoutubeは当然のように英字を打っていたので気づかなかったけど、日本語を打つ場合だとちょっと勝手が変わってくる。

なにやら、ブラウザによって、upの判断が違うようで・・・というかなんと言えばよいか(笑)

以下に表にしてみました。(すべてWinXP

IE 6.0 常にイベントが発生。
Firefox 2.0 Enterを押下→文字列を確定し、下線が消えた瞬間にイベントが発生
Opera 9.2 文字列を確定してもイベントは発生しない


むちゃバラバラ。IEとFirefoxの違いくらいならいいのだが(というかむしろ変換前にイベントは発生しないでほしいが)、Operaのはいただけない。*2
IEの「常に」とは、例えば、打っている途中で「どらごn」なんかでもイベントは発生している。つまり、「d」「ど」「どr」「どら」「どらg」「どらご」「どらごn」の各回にてイベントが発生している。ちなみにFirefoxの場合は、「ドラゴン」と確定したとき一度だけイベントが発生する。

で、Operaは・・・。確定した後、「Enter」とか押せば、イベントは発生する。(もちろんEnterが押されてKeyupが判定されるんだな。)


で、これじゃまずいぞ、と思いまして。Operaなんでどうせシェアねーし!とか言われても、私は大好きなので仕方がない(笑)


というわけで、もうしょうがないよ、prototypeの、Event.Element.Observer使いました。0.8秒間隔くらいで判定することにしてみた。

具体的には、

function searchExe(){
	new Form.Element.Observer ('searchbox', 0.8, 
		function (element, value) {
		    new Ajax.Updater(
		        'result',
		        'search.php',
		        {
		            parameters : $H({query:value}).toQueryString()
		        }
		    );
		}
	);
}

window.onload = searchExe();

みたいなカンジにしておきました。*3

いいのかな?これで。。
ああ、ちなみにこのEvent.Element.Observerですが、0.8秒ごとに値をチェックしに行くので、よくないよね!みたいな議論も色々なところでされているみたいですね。だから必要が無くなったときに(例えば要素そのものが消えたとか)、こいつをストップさせる!みたいなprototype.jsのハックしてる方もいました。やっぱそういうの必要なのかなあ?



もうホントJavascriptは自信なくてイヤだ。

まあでも、これもいじってるうちになにかいい方法思いついたり、素敵なことができるようになったりするんだ!そんな気がする!!そしてこうやってブログでさらしてれば恥ずかしさあまりに勉強するし(笑)

それにしても、Ajaxはあまりに楽しいです。

*1:ていうか、これって、いいの?通信はキーを押す回数分発生するんだけど。まあこれについても後述しますが…

*2:自宅ではOperaなので帰ってきて試して初めて気づいた。え、Operaなんて無視?いやいや、かゆいところに手が届くシステム…つか自分のメインブラウザなのでかゆいっていうかかゆすぎなんじゃ!

*3:ちなみに、サラっと言ってみせたけど、この「window.onload」を、searchboxの要素より前に記述して、「要素がありません(的な。Firebugで。)」のエラーに数十分悩まされたことは、おおっぴらには言わないことにしておく。エレメントがないのに探しに行く、ってこういうことなんですね。