LoginSignup
7
3

More than 5 years have passed since last update.

【javascript】iOSに物理キーボードをつないでkeyupイベントでどのキーがupされたかを取得する

Last updated at Posted at 2018-04-11

iOSの困った現象

iOSのデバイスに物理キーボードをbluetoothや有線でつないで操作するケースはままあると思います。

今日お客さんからiPadにつないだキーボードだと操作ができない旨のお話をいただき調べたところ、iOS+物理キーボード+safariの組み合わせでkeyupイベントのevent.keyCodeがみんな0になってしまうという不具合(仕様?)がありました。

結構前からそうみたいです。

StackOverflowにも同様の質問がいくつかありましたが解決はしていない模様。

https://stackoverflow.com/questions/28944171/e-keycode-in-ios-safari-on-keyup-event
↑現象は説明してくれてるんだけど答えが載ってない... ちなみにevent.whichも0でした。

https://stackoverflow.com/questions/45924702/ipad-bluetooth-keyboard-returns-keycode-of-0-for-any-key-with-onkeyup
↑矢印キーとESCなら取得できる

今回やりたかったこと

キーボードの特定のキーが押されている時間を取得したかったのでkeydownイベントとkeyupイベントの組み合わせがどうしても必要でした。

対応案

  1. keyup自体は動作する(keyCode=0が返るが...)のでkeypressでkeyCodeを取っておいてkeyupは取っておいたkeyCodeのkeyupとみなす
     (→複数キーの同時押しに対応できない!)

  2. iPadはiOSのせいにして諦める
     (→iPad前提の案件のため不可!)

  3. 上にあるように矢印キーを駆使して代替する
     (→最大で5つぐらいキーを押す必要があるため矢印キーだと足りない、ESCもあるけどちょっと)

  4. アプリにすれば何とかなる??
     (→アプリ経験ないので不可!)

  5. iPadはやめてsurfaceにしたらどうかと、surfaceの営業をかける

思いつくのはこれぐらいでしょうか。

調査

みんなできない言うても自分で調べないと納得できないので、調査を行います。
調査といってもeventの中身を見るだけですが。

  1. 手持ちのiPhoneを手持ちのmacと有線でつなぎます。
  2. iPhoneの「設定」>「safari」>「詳細」>「webインスペクタ」を有効にします。
  3. iPhoneとBluetoothでAppleのキーボードをペアリングします。
  4. サンプルのwebpageをiPhoneのsafariで開きます。
  5. macのsafariの開発者ツールから自分のiPhoneを指定します。
  6. iPhoneのsafari上でAppleのキーボードにてkeyupを行います。
  7. macのデバッガでconsole.log(event)の中身を見てみます。

コードは至ってシンプル(jquery)

$(function(){
  $(document).keyup(function(ev){
    console.log(ev);
  });
});

調査結果

1キーを押下してみました。logは取れましたが...

altGraphKey: false
altKey: false
bubbles: true
ancelBubble: false
cancelable: true
charCode: 0
code: "Unidentified"
composed: true
ctrlKey: false
currentTarget: null
defaultPrevented: false
detail: 0
eventPhase: 0
isComposing: false
isTrusted: true
key: "Dead"
keyCode: 0
keyIdentifier: "Unidentified"
keyLocation: 0
layerX: 0
layerY: 0
location: 0
metaKey: false
pageX: 0
pageY: 0
repeat: false
returnValue: true
shiftKey: false
srcElement: <body>
target: <body>
timeStamp: 132920459935500700
type: "keyup"
view: Window {}
which: 0

本当にcharCodeもkeyCodeもwhichも0...
キーを判定できそうな情報は皆無です。

解決方法

surfaceの営業マンになるしかないかと諦めかけていたのですが、いろいろいじくってたらログにkey: "1"が出ました。

なんでだろうと思って2のキーを押してみるとちゃんとkey: "2"が…

よくよく見てみるとinputタグのtext入力欄にフォーカスされていました。
textにフォーカスされている状態でkeyupを行うとevent.keyに押下したキーが取得できるようです。

ここまで取れればあとは何とかできそう。

<input type="text" id="tmp"/>をどっかに隠して用意しておいて、

var current_key = undefined;
$(document).keydown(function(event){
  $("#tmp").focus();
  if(event.key) {
    if(event.key !== "Dead"){
      current_key = event.key;
    }
  }
}).keyup(function(event){
  if(event.key === current_key) {
    something()
  }
  current_key = undefined;
});
$("#tmp").blur(function(){
  if(current_key !== undefined){
    something();
  }
  current_key = undefined;
});

function something(){
//何か処理
}

keydownでテキストボックスにfocus()しておいて、keyup時のkeyを取得、何かの拍子にテキストボックスのfocus()が外れてしまったらそこでkeyupしたこととみなす、

尚windowsではshiftキー単体のkeyupでevent.keyに"Shift"とはいったのですが、iPad+物理キーボードではkeyupイベント自体が動きませんでした。

この辺りはどうしようもなさそうです。

まとめ

・iOS+物理キーボード+safari環境でkeyupイベントは実行できるがevent.keyCodeが常に0
・上記環境のkeyupを使いたい場合は、テキストボックスにフォーカスした状態でkeyupし、event.keyにて打たれたキーの文字を取得する必要がある。
・ShiftキーやAltキーなどの単体のkeyupイベントは上記環境では取得できない。

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3