web-dev-qa-db-ja.com

Android JavaScriptを使用した仮想キーボードで入力されたキーをキャプチャする

テキストエリアのあるWebページがあり、ユーザーが入力したキーをキャプチャする必要があります(入力したキーを別のUnicode文字に置き換えることができます)。私の現在のコードは次のとおりです。

$("#myTextArea").bind('keypress', function(event) {

    var keyInput = event.which;
   // call other functions

});

上記のコードは、PCおよびiPhone/Safariで機能します。ただし、それはAndroidでChrome)を使用すると失敗します(サムスン)タブレット。Android仮想(ソフト)キーボードで入力すると、何らかの理由で、 「keypress」イベントはトリガーされません。Androidバージョンは5.0.2です。

"keyUp"または "keyDown"を使用しようとすると、すべての文字に対して常に229が返されます(リターンキー、スペース、バックスペースなどを除く)。

KeyCodeは常に229ですが、textareaにはユーザーが入力した正しい文字が表示されます。つまり、デバイスはどのキーが入力されたかを知っていますが、JavaScriptを使用してこのイベント(およびキーコード)のハンドルを取得することができません。

これまでに試した代替案とその結果を以下に示します。

$("#mainTextArea").on("keydown keyup", function(event) { 
    // event.which and event.keyCode both return 229

$(document).on('keypress', function(event) { 
    // function is not triggered

$('#myTextArea').bind('input keypress', function(event) { 
   // comes inside function, but keyCode and which are undefined

この問題に関するヘルプを歓迎します。

32
agentwarn

残念ながら、ここでは多くのことを実行できないようです。 Keypressイベントは非推奨であるため、発生しません。キーアップおよびキーダウンの229は、キーボードバッファがビジーであることを示します。理由-キーを押したとき-入力は、ユーザーが押したものであることが保証されていません。これは、オートサジェストや、すぐに続いてイベントを無効にする可能性がある他のイベントのためです。私の意見では、最初にキーを送信してから、おそらく自動提案で別のイベントを発生させて、個別に行動することができたはずです...

現在知っている唯一のものは、キーダウンとキーアップの両方にアタッチすることです。キーダウンの値を保存し、キーアップの値を取得し、ユーザーが押したデルタを見つけます。残念ながら、これは非入力コントロール(たとえば、ボディまたはそのようなもの)では機能しません。たぶん、答えとして聞きたいことではありませんが、それでもです。

10
Pavel Donchev

私は同じ問題に遭遇しました。いくつかの説明が出ていますが、とにかく解決策が提供されていないのは奇妙に思えます。今のところ oninput イベントをキャプチャすることで解決しました。

「このイベントはonchangeイベントに似ています。違いは、要素の値が変更された直後にoninputイベントが発生し、コンテンツが変更された後、要素がフォーカスを失うとonchangeが発生することです。」

このイベントは、テキストの貼り付けまたは修正と提案からの挿入テキストもサポートします。

テキストを入力した後にしか操作できないので、完璧な解決策は得られませんが、現時点ではそれが最高です。

誰かがより良い解決策を持っているなら、私はそれについて聞いてうれしいです。

6
user2299401

私が取り組んでいたプロジェクトの研究をしているときに、この議論に出会いました。モバイルアプリの入力マスクを作成する必要がありました。 Pavel Donchevの答え Androidでキーをキャプチャするために何が有効かを考えさせられました。私の特定のプロジェクトでは、キーアップイベントはキーがリリースされた後にのみトリガーされるため、キーダウンとキーアップは十分ではなく、検証の遅れを意味するため、入力イベントでさらに調査(および多くの試行錯誤)を行いましたそして、それを機能させました。

var input = document.getElementById('credit-card-mask'),
    oldValue,
    newValue,
    difference = function(value1, value2) {
      var output = [];
      for(i = 0; i < value2.length; i++) {
        if(value1[i] !== value2[i]) {
          output.Push(value2[i]);
        }
      }
      return output.join("");
    },
    keyDownHandler = function(e) {
      oldValue = input.value;
      document.getElementById("onkeydown-result").innerHTML = input.value;
    },
    inputHandler = function(e) {
      newValue = input.value;
      document.getElementById("oninput-result").innerHTML = input.value;
      document.getElementById("typedvalue-result").innerHTML = difference(oldValue, newValue);
    }
;

input.addEventListener('keydown', keyDownHandler);
input.addEventListener('input', inputHandler);
<input type="text" id="credit-card-mask" />
<div id="result">
  <h4>on keydown value</h4>
  <div id="onkeydown-result"></div>
  <h4>on input value</h4>
  <div id="oninput-result"></div>
  <h4>typed value</h4>
  <div id="typedvalue-result"></div>
</div>

Oninputイベントは、keydownイベントの直後にトリガーされます。これは、検証に最適なタイミングです。

すべてを記事にまとめました。興味があれば、それについて読むことができます here

4
Glauber Borges

入力した文字を提供するtextInputイベントがあります

const inputField = document.getElementById('wanted-input-field');

inputField.addEventListener('textInput', function(e) {
    // e.data will be the 1:1 input you done
    const char = e.data; // In our example = "a"

    // If you want the keyCode..
    const keyCode = char.charCodeAt(0); // a = 97

    // Stop processing if "a" is pressed
    if (keyCode === 97) {
        e.preventDefault();
        return false;
    }
    return true;
});
2
reyiyo

入力文字のkeyCodeを確認します。0または229の場合は、JSのcharCodeAtを使用して、入力文字列をパラメーターとするKeyCodeを返す関数getKeyCode()を使用します。最後の文字のキーコードを返します。

<script>
        var getKeyCode = function (str) {
            return str.charCodeAt(str.length);
        }


        $('#myTextfield').on('keyup',function(e){

            //for Android chrome keycode fix
            if (navigator.userAgent.match(/Android/i)) {

                var inputValue = this.value;

                var charKeyCode = e.keyCode || e.which;
                if (charKeyCode == 0 || charKeyCode == 229) { 
                    charKeyCode = getKeyCode(inputValue);
                    alert(charKeyCode+' key Pressed');
                }else{
                   alert(charKeyCode+' key Pressed');
                    }
            }       
        });
    </script>
2
Akshay Tilekar

私は最近、最新バージョンのAstro AI Assisted Emailアプリに「メンション」機能を実装しました。基本的に、作成Webビューで「@」と入力すると、オートコンプリート候補のリストが表示されます。私たちは、他のほとんどの人々と同様に、Javascriptでこれを解決しようとして問題を抱えていました。最終的に機能したのはネイティブソリューションでした。 WebViewのonCreateInputConnection()メソッドを@Overrideする場合、super.onCreateInputConnection()の結果(単なるInputConnectionインターフェイス)をカスタムクラスでラップできます。次に、ラッパーの実装で、commitText()またはsetComposingText()を介して入力をトラップできます。上矢印や下矢印などの制御文字でコールバックが発生するかどうかはわかりませんが、特定の問題の解決を開始する場所になる可能性があります。

1
Anthony Lee