val()を使用してselectの値を設定すると、jquery changeイベントがトリガーされないのはなぜですか?


377

change()イベントハンドラーのロジックは、によって値が設定されている場合は実行されval()ませんが、ユーザーがマウスで値を選択した場合は実行されます。どうしてこれなの?

<select id="single">
    <option>Single</option>
    <option>Single2</option>
</select>

<script>
    $(function() {
        $(":input#single").change(function() {
           /* Logic here does not execute when val() is used */
        });
    });

    $("#single").val("Single2");
</script>

回答:


589

このchangeイベントには、JavaScriptコードではなくユーザーが開始した実際のブラウザイベントが必要なためです。

代わりにこれを行ってください:

$("#single").val("Single2").trigger('change');

または

$("#single").val("Single2").change();

1
こんにちは、この更新ドロップダウンを行います。しかし、onChange()が再帰的に呼び出されます。
Pankaj

3
私はこの答えを掘ります。それは機能しますが、jQueryを使用するより良い方法はありませんか?変更ハンドラーが設定されている値(皮肉)を変更するたびに、必ずこれを行うことを忘れないでください。データバインディングを使用するフレームワークは、これをよりよく解決できますか?
Jess

@ user113716値を知らずにそれをタイガーする方法を知っていますか?
BKSpurgeon

4
これが正しい答えだと私は同意しますが、これは私がやろうとしていることを完全に吸い込み、台無しにします。
ダスティンポワサント2016年

$( "#single")。trigger({type: "change"、val: "Single2"})を
試してください

44

手動で変更イベントをトリガーできると思いますtrigger()

$("#single").val("Single2").trigger('change');

なぜ自動的に発火しないのかはわかりません。


私はこれを機能させることができません、また$( "#single")。val( "Single2")。change(); 私は動的にドロップダウンを作成し、その値を変更しています(それは私にとってはうまくいきます)しかし、変更をトリガーしようとすると、それは私にとってはうまくいきません。
Maneesh Kumar 2013

4
「ビット」は遅れますが、無限ループにつながるため、自動的に起動しません。考える$('#foo').change(function() { $( this ).val( 'whatever' ); });
JJJ 2014年

@Juhana無限ループの方がval()が不思議なことに「変更」バインディングのトリガーに失敗するよりも、通知、診断、修正がはるかに簡単だと思います。
iono 2016

.change()の呼び出しは、.trigger( 'change')の呼び出しの省略形です。
Triynko 2016年

9

val()の後にこのコードを追加すると機能するようです。

$(":input#single").trigger('change');

6
はい。ただし、でDOMを個別に選択する必要はありません$(":input#single")。実際、そうすべきではありません。後にチェーンするだけです.val().trigger('change')またはを使用できます.change()。それらはまったく同じです。
user113716 2011年

8

私がAPIで読むことができる限り。イベントは、ユーザーがオプションをクリックしたときにのみ発生します。

http://api.jquery.com/change/

選択ボックス、チェックボックス、およびラジオボタンの場合、ユーザーがマウスで選択を行うとすぐにイベントが発生しますが、他の要素タイプの場合、要素がフォーカスを失うまでイベントは延期されます。


他の要素タイプの代替は何ですか?input要素がフォーカスを失ったときではなく、要素に対して 'change'イベントをすぐに発生させたい。あなたは知っていますか?
Dan

1
「即時」とは、「入力でキーが押されたとき」を意味し、onchangeではなく、onkeyup、onkeypress、onkeydownイベントを探します。
user2867288 2016年

6

簡単にカスタム関数を追加し、値を変更すると変更がトリガーされるようにしたいときに呼び出す

$.fn.valAndTrigger = function (element) {
    return $(this).val(element).trigger('change');
}

そして

$("#sample").valAndTirgger("NewValue");

または、valが呼び出されたときに常に変更を呼び出すようにval関数をオーバーライドできます

(function ($) {
    var originalVal = $.fn.val;
    $.fn.val = function (value) {
        this.trigger("change");
        return originalVal.call(this, value);
    };
})(jQuery);

http://jsfiddle.net/r60bfkub/のサンプル


私のブラウザは再帰が多すぎると不平を言っています、これに対する修正はありますか?
Bhargav Nanekalva

あなたは、のために聞いているchangeコントロールの上に-eventと(直接または間接的に)再トリガするコールバックを実行中changeに同じ制御を超える-eventを。手動でトリガーするイベントには別の名前を使用することをお勧めします(例:)。これにより、-eventがexplicit.change再トリガーchangeされず、ループが防止され、イベントに反応できるようになります。
カマフェザー

3

デフォルトの変更イベントと混同したくない場合は、カスタムイベントを提供できます

$('input.test').on('value_changed', function(e){
    console.log('value changed to '+$(this).val());
});

値セットでイベントをトリガーするには、次のことができます

$('input.test').val('I am a new value').trigger('value_changed');

3

WordPressでCMB2を使用しているときに同じ問題に遭遇し、ファイルアップロードメタボックスの変更イベントにフックしたいと思いました。

したがって、変更を呼び出すコード(この場合はCMB2スクリプト)を変更できない場合は、以下のコードを使用してください。値が設定された後でトリガーが呼び出されます。それ以外の場合、変更eventHandlerは機能しますが、値は設定されている値ではなく、前の値になります。

これが私が使用するコードです:

(function ($) {
    var originalVal = $.fn.val;
    $.fn.val = function (value) {
        if (arguments.length >= 1) {
            // setter invoked, do processing
            return originalVal.call(this, value).trigger('change');
        }
        //getter invoked do processing
        return originalVal.call(this);
    };
})(jQuery);

これは良いことですが、特定の入力を1つに制限する方法を示すことができますか?
jwebb

@jwebbどういう意味かわからない?jQuery val()関数をオーバーライドしています。変更イベントハンドラーを特定の入力にバインドします。
user2075039 2018

つまり、@ user2075039、jQuery val()関数を使用してページに複数の入力があり、カスタム変更イベントハンドラーをそれらのすべてではなく1つにバインドしたくない場合はどうなりますか?
jwebb 2018

@jwebb 特定のセレクターについてthis.selector、オーバーライド$.fn.val関数内でチェックできます(セレクターに使用されるものに依存します)。これは私が特定のフィールドに対してのみこれを行うために見つけた最高のものです、唯一の問題は、セレクタに何が使用されているかを知る必要があることです
sMyles

1
$(":input#single").trigger('change');

これは私のスクリプトでうまくいきました。3つのコンボがあり、chainSelectイベントでバインドします。URLで3つの値を渡す必要があり、デフォルトですべて選択ドロップダウンします。これを使った

$('#machineMake').val('<?php echo $_GET['headMake']; ?>').trigger('change');

そして、最初のイベントは成功しました。


10
私はあなたがこれを現実の世界で決してしないことを望みます。$ _GET ['whatever']は信頼できないことは言うまでもありません。
Denis V

1

フォームに選択オプションを追加したばかりで、変更イベントをトリガーしたい場合、setTimeoutが必要であることがわかります。そうでない場合、jQueryは新しく追加された選択ボックスを取得しません。

window.setTimeout(function() { jQuery('.languagedisplay').change();}, 1);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.