web-dev-qa-db-ja.com

押されたキーが<input>テキストボックス内に文字を生成するかどうかを検出する方法は?

通常のテキストボックスがあります。

<input type="text"> 

JQueryを使用してキー関連のイベントを処理します。

$("input:text").keydown(function() {
    // keydown code
}).keypress(function() {
    // keypress code
}).keyup(function() {
    // keyup code
});

ユーザーはテキストボックスに焦点を合わせ、キーボードのさまざまなキーを押します(通常のキー:文字、数字、SHIFT、BACKSPACE、SPACE、...)。ユーザーがテキストボックスの値の長さを増やすキーを押したときを検出する必要があります。たとえば、「A」キーはそれを増やし、「SHIFT」キーはそれを増加させません。

PPKが彼とその2人の違いについて言及した講義を見たことを覚えています。それはイベントと関係があります-keydown vs keypress-そしておそらくイベントのプロパティ-key、c​​har、keyCodeと関係があります。

更新!

Keydownまたはkeypressハンドラー内でこの情報を知る必要があります。キーアップイベントが発生するのを待つことができません。

これが必要な理由:

ユーザー入力に基づいてサイズが動的に変化するテキストボックスがあります。このデモをご覧ください: http://vidasp.net/tinydemos/variable-size-text-box.html

デモでは、キーダウンおよびキーアップハンドラーがあります。キーアップハンドラーは、入力値に基づいてテキストボックスのサイズを調整します。ただし、キーダウンハンドラーは、サイズを入力値より1文字大きく設定します。これを行う理由は、そうしなかった場合、文字がテキストボックスの外側にあふれ、ユーザーがキーを放したときにのみテキストボックスが拡大するからです。これは奇妙に見える。そのため、新しい文字を予想する必要があります。文字がテキストボックスに表示される前に、各キーダウンのテキストボックスをエルゴで拡大します。デモでわかるように、この方法は素晴らしいです。

ただし、問題はBackSpaceキーと矢印キーです。キーダウンでテキストボックスも拡大され、キーアップでのみテキストボックスのサイズが修正されます。

回避策:

回避策は、BackSpace、Shift、およびArrowキーを手動で検出し、それに基づいて動作することです。

// keydown handler
function(e) {
    var len = $(this).val().length;
    if (e.keyCode === 37 || e.keyCode === 39 ||
        e.keyCode === 16) { // ARROW LEFT or ARROW RIGHT or SHIFT key
        return;
    } else if (e.keyCode === 8) { // BACKSPACE key
        $(this).attr("size", len <= 1 ? 1 : len - 1);
    } else {
        $(this).attr("size", len === 0 ? 1 : len + 1);
    }
}

これは、BACKSPACE、SHIFT、ARROW LEFT、およびARROW RIGHTで機能します(そして見栄えがします)。ただし、より堅牢なソリューションが必要です。

34
Šime Vidas

これは仕事をするか、そうでない場合は非常に近く、微調整が必​​要になると思います。覚えておく必要があるのは、keydownまたはkeyupイベントに入力される可能性のある文字については、確実に何も伝えることができないということです。つまり、すべてをkeypressハンドラーで行う必要があります。キーイベントの決定的なリソースは http://unixpapa.com/js/key.html です

また、このコードでは処理できないペーストを考慮する必要があります。別個のpasteイベントハンドラーが必要になります(ただし、このイベントはFirefox <3.0、Opera、および非常に古いWebKitブラウザーではサポートされていません)。 JavaScriptでは貼り付けられようとしているコンテンツにアクセスできないため、貼り付けハンドラーにタイマーが必要になります。

function isCharacterKeyPress(evt) {
    if (typeof evt.which == "undefined") {
        // This is IE, which only fires keypress events for printable keys
        return true;
    } else if (typeof evt.which == "number" && evt.which > 0) {
        // In other browsers except old versions of WebKit, evt.which is
        // only greater than zero if the keypress is a printable key.
        // We need to filter out backspace and ctrl/alt/meta key combinations
        return !evt.ctrlKey && !evt.metaKey && !evt.altKey && evt.which != 8;
    }
    return false;
}

<input type="text" onkeypress="alert(isCharacterKeyPress(event))">
29
Tim Down

私が見つけることができる解決策は、イベントのキーの長さをチェックすることです。

例えば:-

<input type="text" id="testId" onkeyup="keyChecking(event)" />

<script type="text/javascript">
function keyChecking(event) {

    if (event.key.length == 1) {
        alert("key produced character " + event.key);
    } else {
        alert("Key DOES NOT produce character");

        const alphabets = "AZaz09";
        const key = event.key;
        var notEvenASymbol = false;

        for (let i = 0; i < key.length; i++) {
            var charCode = key.charCodeAt(i);
            if ((charCode >= alphabets.charCodeAt(0) && charCode <= alphabets.charCodeAt(1)) ||
                (charCode >= alphabets.charCodeAt(2) && charCode <= alphabets.charCodeAt(3)) ||
                (charCode >= alphabets.charCodeAt(4) && charCode <= alphabets.charCodeAt(5))
            ) {
                notEvenASymbol = true;
                console.log(charCode);
                break;
            }
        }

        if (notEvenASymbol) {
            alert("Key DOES NOT produce even a symbol");
        }
        console.log(event.key);

    }
}    
</script>

したがって、文字/記号を押すと、event.keyにはその文字が含まれ、その長さは1になります。文字[〜#〜] v [〜#〜]を押すと、event.keyには値[〜#〜] v [〜#〜]がありますが、Enterキーを押すと値Enter、shiftを押してからShiftなどを押します。したがって、キーが文字を生成しない場合、その長さは1より大きくなります。

更新済み

キーボードの一部の特殊キーは記号を生成し、その長さは1より大きくなる可能性があるため、記号ではない場合でも警告できるようにコードを変更しました。例:-????その長さは2です。一部のモバイルキーボードには、このような記号のショートカットキーがあります。

キーボードの非文字/記号キーは、常にアルファベット、数字、またはその両方の組み合わせになります。例:-F2Shift

このシナリオに注意を向けてくれた@Vicky Chijwaniに感謝します。

9
Visruth

はるかに単純な解決策があり、これは私にとってはうまくいきました:

if(String.fromCharCode(event.keyCode).match(/(\w|\s)/g)) {
  //pressed key is a char
} else {
  //pressed key is a non-char
  //e.g. 'esc', 'backspace', 'up arrow'
}

これには、DOM要素を調べる必要はありません(待ち時間とlatencyさを追加します)。

9
MikeX

OK、私はそれを持っていると思います。解決策は少しハックですが、実際には本当にうまく機能します。

キーダウンで、入力ボックスの長さをチェック/変更する関数を呼び出す1ミリ秒のsetTimeoutを実行します。

http://jsfiddle.net/rygar/e2wQM/

特にバージョンが機能しないいくつかの場所(バックスペース、CTRL + V、またはテキスト全体を選択して削除を押すなど)で特にうまく機能しているようです。

編集:0ミリ秒の遅延を持つsetTimeoutでも動作するようです!

4
Jeff

Keydown関数でプロパティkeyEventArgs.Keyを使用する必要があります。これにより、システムに依存する数値が返されます。

さまざまなブラウザとOSのさまざまなキーコードを含むリンクを次に示します。

http://www.quirksmode.org/js/keys.html

3
mariana soffer

これは探している方法ではないかもしれませんが、キーダウン関数でthis.value.lengthの値を確認するだけです。戻り値は、新しい文字が追加される前の入力フィールド内のテキストの長さです。したがって、キーアップ機能で長さをもう一度チェックすると、ユーザーが文字を押した場合は長さが大きくなりますが、ユーザーがシフトキーを押した場合は同じになります。

1
Jeff

入力フィールドの長さにカウンターを設定していると思いますが、その場合はあまり空想する必要はなく、フィールドの長さを変数に割り当て続けるだけで、ユーザーが最大長は、次のように削除またはバックスペースを押すことのみを許可します:

$("input:text").keypress(function() {
var current = $(this).val().length;
if (current >= 130) {
if (e.which != 0 && e.which != 8) {
e.preventDefault();
}
}
}

現在の変数を使用してカウンターを表示することも、maxlength-currentを使用して、残っている文字数をカウントダウンすることもできます。

1
Liam Bailey

入力したテキストよりもテキストボックスを大きくすることの目標。

テキストボックスに(1人ではなく)2人の追加キャラクターを配置することを計画して、これを実現します。次に:

// pseudo-code.... 
old_len = textbox.value.length
keyUp function() {
  var new_len = textbox.value.length
  if (new_len != old_len) {
    old_len = new_len
    textbox.style.size = new_len + 2 // pseudo code.
  }
}

上記の利点は、キーコードのネザーワールドに降りる必要がないことです。

1
Larry K