keyupはもう古い!! inputイベントを使って、スマホでも安心入力設計

こんにちわ。
1970年代の音楽を聞くと「懐かしい!!!」と感じる下駄です。
ブラウザ対応のWEBサービスを作っていると、必ず問題になるのが、スマートフォン対応です。
ゲームなどのプログラムだとあまり問題になり難いのですが、ビジネス・サービス系であれば、大抵の場合が入力フォームが発生して、PCのIE対応から、スマートフォンの万人アクセスまで、問題なく動作する要求をされがちです。
もちろん、ブラウザ対応とするサービスであれば、このぐらいの覚悟をして挑まなければいけませんが、実際にご完成が難しい状況が発生すると、気が狂いそうになります・・・あqすぇdrftgyふじこlp・・・取り乱してしまいました。(ひさしぶりのふじこですね・・・)
そして、そんな入力フォーム系のハマりがちなポイントとして、キーボード入力判定があります。
鬼門になりがちなキーボードイベント
パソコンを使ってのキーボードイベントといえば、
keydown
keyup
keypress
などがありますが、このへんはどのPCブラウザでもサポートされており、難なく搭載することができるのですが、iOSのデフォルトキーボードを使っていると、2バイト文字を入力する際に、keypressが正常動作しないとか、keyupが反応しないケースが発生します。
最近になって知ったのですが、そんな時は、「input」イベントを使うといいらしいです。
IE6ぐらいからのWEBエンジニアであれば、「なんじゃそりゃ!!!!!」となると思いますが、oninputというイベントがIE9以降から(他のブラウザは比較的古いバージョンから)搭載されています。
inputタグに対して、「入力したよ」というイベントで、keyupよりも使い勝手はいいかもしれません。
少なくともほぼ使われないkeydownよりは使えます。
※何故keydownが使えないかは今回は説明を割愛します。
inputイベントについて
https://developer.mozilla.org/ja/docs/Web/API/GlobalEventHandlers/oninput
リファレンスサイトを見ると、以下のように説明書きが書かれています。
window 上の input イベントのためのイベントハンドラです。input イベントは、 <input> 要素の値が変化したときに発生します。
値が変更されたというのは、keyupと同じ様なタイミングなのでしょうか?
以下のプログラムを実行して少し調べてみました。
1 2 3 4 5 6 7 8 9 10 |
var test = document.getElementsByName("test"); if(test){ test[0].onkeydown = function(e){console.log("key-down : "+e.target.value)}; test[0].onkeyup = function(e){console.log("key-up : "+e.target.value)}; test[0].onkeypress = function(e){console.log("key-press : "+e.target.value)}; test[0].oninput = function(e){console.log("input : "+e.target.value)}; test[0].onTextInput = function(e){console.log("textInput : "+e.target.value)}; test[0].onfocus = function(e){console.log("focus : "+e.target.value)}; test[0].onblur = function(e){console.log("blur : "+e.target.value)}; } |
このHTMLをブラウザで開いて、javascriptコンソールを見てみると以下のような返答が返ってきます。
1 2 3 4 5 6 |
focus : key-down : key-press : input : a key-up : a blur : a |
1 2 3 4 5 6 7 8 9 10 11 |
focus : key-down : key-press : input : a key-up : a key-down : a key-press : a input : aa key-up : aa blur : aa |
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 32 |
focus : key-down : input : s key-down : s input : し key-up : し key-up : し key-down : し input : しn key-up : しn key-down : しn input : しん key-up : しん key-down : しん input : しんj key-up : しんj key-down : しんj input : しんじゅ key-up : しんじゅ key-down : しんじゅ input : しんじゅk key-down : しんじゅk input : しんじゅく key-up : しんじゅく key-up : しんじゅく key-down : しんじゅく input : 新宿 key-up : 新宿 key-down : 新宿 input : 新宿 key-up : 新宿 blur : 新宿 |
たまにダブって2回発生しているkey-upと比べてinputイベントは安定しているように見えます。
そして、keyupとほぼ同じタイミングで同じ挙動をしている事もわかるので、非常に使い勝手はよさそうですね。
iOSで確認
上記確認プログラムをiOSで実行してみます。
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 |
focus : key-down : input : し key-up : し key-down : し input : しん key-up : しん key-down : しん input : しんし key-up : しんし key-down : しんし input : しんじ key-up : しんじ key-down : しんじ input : しんじゆ key-up : しんじゆ key-down : しんじゆ input : しんじゅ key-up : しんじゅ key-down : しんじゅ input : しんじゅく key-up : しんじゅく input : 新宿 input : input : 新宿 blur : 新宿 |
inputが最後の方にブランクになっている瞬間があります。
これは、「完了」または「改行(決定)」をスマホで押した際に発生するようですね。
key-upは、最後の文字列が取得できていないので、この時点でトラブル発生することがよくわかりますね。
これからはinputイベントを使おうっと!!!!