inputで「テキストが変更された」時のみなにかしたい。

XULのイベントで「oninput」というのがある。

<input type="text" value="" oninput="foobar()" />


の様に置いておくと、valueが変更された時に随時イベントが起きる。

JavaScriptにも「onchange」があるじゃないかという声が聞こえそうだが、微妙に違う。

「onchange」は「フォーカスが外れたとき」valueが変更されていたら起きるイベントであり、タイプ中には起こらない。



それでは「onkeydown」「onkeyup」はどうかというと、これもちょっと違う。
「onkeydown」「onkeyup」は「キーが押された(離された)ときに起きる」イベントなので、valueが変更された、されないに関わらず起きる。

なにが言いたいかというと、インクリメンタルサーチがしたかった。
テキストが変更された時のみに、その場でイベントが起きて欲しかった。
valueを使ってリクエストを飛ばすことを考えると、内容が変わってないのに処理をしてしまっては無駄であり、もったいない。

そしてリクエストを飛ばされる側にとっては余計な負荷になり、五月蠅いのであり、おととい来やがれとなってあぁこのIPからのリクエストは無視しましょうそうしましょうということになったりして非常に残念なことになる。

つまり「oninput」の挙動が欲しかった。でもこれはXULのイベントなのでFirefoxでは起きても、IEでは起こらない。これはちょっと困る。

そこで、考えたのがこれ。

var textValue;  // グローバル変数

function theFunc(keyCode, value) {
// テキストが変更されていなかったら処理をしない
if (textValue == value) { return; }

// 以下処理
}

<input type="text" value=""
onkeydown="textValue = this.value"
onkeyup="theFunc(event.keyCode, this.value)" />

コメント

  1. sounisi5011 より:

    > 「onkeydown」「onkeyup」は「キーが押された(離された)ときに起きる」イベントなので、valueが変更された、されないに関わらず起きる。

    この実装では、値の変更をonkeyup時に判定しています。
    このため、この問題は解決できていません。

    キーの操作に関係なく、値の変更を判定するには、(入力欄にフォーカスしている時に)タイマー処理で定期的に値の変更を検証する方法が適切と考えます。

    以下に、私が書いた実装例を例示します:
    http://qiita.com/sounisi5011/items/767392c1f7736e2e5d4c#%E6%96%B0

タイトルとURLをコピーしました