web-dev-qa-db-ja.com

<select>キーボードの使用時に発生しない変更イベント

http://jsfiddle.net/rFEER/

<select id="users">
<option value="1">jack</option>
<option value="2">brill</option>
<option value="3">antony</option>
</select>​

js:

$("#users").change(function(){
    alert($(this).val());
})​

マウスがクリックされるまで(keyup/keydown)を使用するときに変更イベントが発生しない理由

22
mgraph

マウスがクリックされるまで(keyup/keydown)を使用するときに変更イベントが発生しない理由

フォーカスがselectを離れたときにも発生します。これがchangeイベントの仕組みです。

プロアクティブな通知が必要な場合は、changekeydownを監視し(少なくとも、clickも必要な場合があります)、イベントが発生した場合にイベントを処理する必要があります。値は実際には変更されていませんおよびこれらのイベントの一部(たとえば、keydown)が発生するという事実を処理する必要がありますbefore値が変更されるため、イベントを処理する前に少し待つ必要があります。または、代わりにkeyupを使用する SpYk3HHの回答 を参照してください。これはそれほど積極的ではありません(キーのリリースまで更新されないため、望ましい場合があります)が、遅延は必要ありません(setTimeout)以下のコードにあります。

例( ライブコピー ):

HTML(値を自由に変更できるようにしたので、それぞれの名前に合ったものを明確にしました):

<select id="users">
<option value="j">jack</option>
<option value="b">brill</option>
<option value="a">antony</option>
</select>​

JavaScript:

$("#users").bind("keydown change", function(){
    var box = $(this);
    setTimeout(function() {
        display(box.val());
    }, 0);
});

2016年の注意:bindは主に on に置き換えられました。上の例では、「bind」を「on」に置き換えるだけです。

30
T.J. Crowder

変更してみてください

_$("#users").change(function(){
_

_$("#users").bind('change keyup', function(e) {
_

これは、両方のychange関数、onchangeイベント、および上下の矢印キーが押された場合にバインドする必要があります

キーダウンを使用することもできますが、選択した変更が行われる前にコードが実行されるため、期待どおりに実行されない場合があります。

無限のスクロール選択ボックスが必要な場合は、これまでに書いた気の利いた小さな機能があります。少なくとも、私にとっては完璧に機能し、他のキーアップアクションに影響を与えることなく、それ自体をすべて割り当てることができます。私たちの目には、これはキーアップに取り組むことを目的としているため、実際には矢印キーを何度も押す必要がありますが、すべてのオプションを介してループを続けます。キーダウンでも動作することは確かですが、そのように使用しないため、テストしていません。繰り返しになりますが、特にselectに2つまたは3つのオプションしかない場合、キーダウンは意図したとおりに実行されない可能性があります。

_function selectInfinateScroll() {
    if ($(this).data("lastSelected")) {
        if ($(this).data("lastSelected")[0] == $(this).children("option:selected")[0]) {
            if ($(this).children("option:selected").index() == 0) {
                $(this).children("option:selected").prop("selected", false);
                $(this).children("option:last-child").prop("selected", true).change();
            }
            else {
                $(this).children("option:selected").prop("selected", false);
                $(this).children("option:first-child").prop("selected", true).change();
            };
        };
    };
    $(this).data("lastSelected", $(this).children("option:selected"));
}

$(function() {
    //  Enable 'Scrolling Through' on Select Boxes
    $("select").keyup(selectInfinateScroll);
});
_

更新しました!


元の答えはそのままにしておきます。これは、一部の人にとってより便利な代替方法を使用しているためです。しかし、私は「キーダウン」で機能する短い関数と、ユーザーが「キーを押したまま」矢印キーを押しながらオプションを無限にソートできるこの関数を使用するjQueryプラグインの両方を考え出しました!

まず、新機能

_function keydownInfiniteSelect(e) {
    var eKey = e.which || e.key,
        selected = $(this).find("option:selected");
    if (eKey == 38 && selected.is(":first-child")) {    //    up arro
        $(this).find("option").last().prop("selected", true);    //    set value to last option
        $(this).change();    //    ensure select triggers change do to return false
        return false;    //    keeps select from skipping to second last option
    }
    else if (eKey == 40 && selected.is(":last-child")) {    //    down arro
        $(this).val($(this).find("option").first().val());    //    set value to first option
        $(this).change();    //    ensure select triggers change
        return false;    //    keeps select from skipping to second option
    }
}
_

次のように使用します:$("select").keydown(keydownInfiniteSelect);

そして、jQueryプラグインスタイル!

_(function($){$.infiniteSelect||($.extend({infiniteSelect:function(b){return b.each(function(){$(this).data("infiniteSelect")||($.fn.on?$(this).on("keydown",$.infiniteSelect.methods.keydownInfiniteSelect).data("infiniteSelect",!0):$(this).bind("keydown",$.infiniteSelect.methods.keydownInfiniteSelect).data("infiniteSelect",!0))})}}),$.fn.extend({infiniteSelect:function(){return $.infiniteSelect($(this))}}),$.infiniteSelect.methods={keydownInfiniteSelect:function(b){b=b.which||b.key;var c=$(this).find("option:selected");
if(38==b&&c.is(":first-child"))return $(this).find("option").last().prop("selected",!0),$(this).change(),!1;if(40==b&&c.is(":last-child"))return $(this).val($(this).find("option").first().val()),$(this).change(),!1}})})(jQuery);
_

として使用$("select").infiniteSelect()[〜#〜]または[〜#〜]$.infiniteSelect("select")

プラグインのjsFiddle ミニ消えた

ノーカットプラグインフィドル

PS。メソッドの「最後に設定するオプション」の部分が消え続けるか、nullになるか、最後から2番目にスキップすることを除いて、関数の準備ができているバニラJavaScriptをほぼ用意しています。正しく設定できないようです。誰かがそれを修正して更新したいのなら、私は大いに義務付けられるでしょう。 [〜#〜]こちら[〜#〜] を参照してください

18
SpYk3HH

それが正常な動作です...

w3c specs を引用する

変更
変更イベントは、コントロールが入力フォーカスを失い、フォーカスを得てからその値が変更されたときに発生します。このイベントは、INPUT、SELECT、およびTEXTAREAに対して有効です。素子。

5

上記の答えを使用して、私は必要な動作を得ることができました:

$( "select" ).bind('keyup', function(e) {
    $(  '#' + e.target.id ).trigger('change');
});
1
Onshop