web-dev-qa-db-ja.com

ASCII制御文字のhtml入力テキスト

Javascriptブラウザアプリでバーコードスキャナーからの入力を処理しようとしています。スキャナー出力は文字列であり、少なくとも1つのグループ区切り文字(ASCII 29)も含まれています。

入力をnotepad ++に向けると、グループ区切り文字を含めて入力が正しく表示されます。入力を<input type="text"> htmlフィールドに送ると、グループ区切り文字オ​​ブジェクトが失われます。フィールドには表示されず、JavaScriptコードでは検出できません。

<input type="text">オブジェクトはASCII制御文字を切り捨てますか?それを回避する方法はありますか?

編集:これを実現するためにRaidoxの回答に似たコードを使用しています:

    inputField.onkeypress = catchGroupSeparatorAndEnter;
    var fncChar = String.fromCharCode(29);

    function catchGroupSeparatorAndEnter(event) {
    if (event.ctrlKey && event.which === 29) {
    inputField.value = inputField.value + fncChar;      
    event.preventDefault();
    event.stopPropagation();
}
...
}

これはChromeとEdgeで機能するようですが、Firefoxでは機能しません。そこで機能させる方法がわかりません。

10
user2007080

私もこの1週間、仕事でこれに苦労してきましたが、今日ようやく突破口を開きました。バーコードスキャナーがどのように機能するかはわかりませんが、USBキーボードのように機能し、個々のキーを押します。 [GS]のキー押下を送信しますが、イベントはブラウザによって自動的にキャンセルされます。したがって、入力イベントに到達することはありません。入力イベントは、入力に文字を追加するイベントです。キャンセルを防ぐ方法がわかりませんでしたが、keypressイベントで手動で入力に文字を追加することでこれを回避できます。

アプリケーションで使用しているフレームワークはわかりませんが、これをカスタムディレクティブに組み込むことで、AngularJSでこれを機能させることができました。以下の例は単なるVanillaJavaScriptですが、使用している可能性のある任意のフレームワークに実装できるはずです。

バニラJavaScriptの例

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Control Character Test</title>
    </head>
    <body>
        <input type="text" id="tacos" />
        <script>
            document.getElementById('tacos').addEventListener('keypress', function(e) {
                if (e.charCode === 29) {
                    this.value += String.fromCharCode(e.which);
                }
            });
        </script>
    </body>
</html>

上記のコードをHTMLファイルに保存して、このアプローチがバーコードスキャナーで機能するかどうかをテストできます。これがそのまま機能しない場合は、すべてのキーを押すようにバーコードスキャナーを再プログラミングすることで、検討する価値のあるもう1つの可能性があります。

別の関連する行動

私の研究では、入力が他の文字と同時に送信された場合、これらの文字を受け入れることもわかりました。たとえば、バーコードデータを1つのイベントとして送信する別のバーコードスキャナーがあります。ブラウザは[GS]文字でこの入力を受け入れます。コピー/貼り付けでこれを行うこともできます。この動作を悪用して、必要なものを取得できる可能性があります。

ブラウザの問題

使用しているブラウザが原因で、これらのアプローチのいずれかで問題が発生する可能性があることも覚えておく価値があります。データを一度に送信するバーコードスキャナーはAndroidデバイスです。クロムと独自のブラウザーの2つのブラウザーがあります。[GS]文字はクロムで表示されますが、独自のブラウザ。

お役に立てれば!

3
Raidox

入力コントロールは、[GS]のような印刷不可能な文字を無視します

ただし、バーコードスキャナーは通常、この文字を次のようにエミュレートします。 CTRL+]onkeydownイベント(キーコード17および221)でキャプチャできます:

    var ctrlPressed = false;
    yourInput.addEventListener('onkeydown', function (event) {
       ctrlPressed = 17 === event.keyCode;
       if (221 === event.keyCode && ctrlPressed)
          // do what you want here (ie. modify the input value)
    });

これが機能しない場合は、最初にコードをログに記録して確認することをお勧めします。

    yourInput.addEventListener('onkeydown', function (event) {
      console.log(event.keyCode)
    });
1
KeatsPeeks

私も同じ問題を抱えていました。イベントリスナーのアイデアに基づいて、IE/ChromeとFirefoxのカスタムソリューションを作成しました。

IE + Chrome(Raidoxソリューション):

document.getElementById('scanfield').addEventListener('keypress', function(e) {
    if (e.which === 29) {
        this.value += String.fromCharCode(e.which);
    }
});

Firefox:

var altValue = '';
document.getElementById('scanfield').addEventListener('keypress', function(e) {
    if(e.altKey){
        altValue += String.fromCharCode(e.which)
        if(altValue == '0029'){
            this.value += String.fromCharCode(29);
            altValue='';
        }
    }
});

Edgeはそのままで機能します。

0
ssindelar

FirefoxはALTキー押下を送信せず、キーダウンイベントとキーアップイベントのみを送信します。
これは各ブラウザで機能します。

//GS1 Datamatrix <GS> in Firefox, Chrome & IE
var altValue = '';
document.getElementById('SKAN').addEventListener('keydown', function(e) {
    if(e.altKey){
        if(e.which != 18){
           altValue += e.which
        }
        if(altValue === '969698105'){
           this.value += String.fromCharCode(29);
        }
    }
});
document.getElementById('SKAN').addEventListener('keyup', function(e) {
    if(e.altKey === false){
      altValue = '';
    }
});
0
Sebastian G