Val () kullanarak bir seçimin değerini ayarladığımda jquery change olayı neden tetiklenmiyor?


377

change()Olay işleyicisindeki mantık , değer tarafından ayarlandığında val()çalıştırılmaz, ancak kullanıcı fareleriyle bir değer seçtiğinde çalışır. Bu neden?

<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>

Yanıtlar:


589

Çünkü changeolay kullanıcı tarafından yerine JavaScript kodu aracılığıyla başlatılan bir gerçek tarayıcı olayı gereklidir.

Bunun yerine şunu yapın:

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

veya

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

1
Merhaba, bu güncelleme açılır listesini yapıyor. ancak özyinelemeli olarak onChange () çağrılır.
Pankaj

3
Bu cevabı kazıyorum. Çalışıyor, ancak jQuery ile daha iyi bir yol yok mu? Eminim TÜM bir değişiklik işleyicisi (alaycılık) ayarlanmış bir değeri her değiştirdiğimizde bunu hatırlayacağız. Veri bağlama kullanan çerçeveler bunu daha iyi çözebilir mi?
Jess

@ user113716 Herhangi bir değer bilmeden nasıl kaplanacağınızı biliyor musunuz?
BKSpurgeon

4
Bu doğru cevap olduğunu kabul ediyorum ama bu kesinlikle yapmaya çalıştığım şeyleri berbat ve mahvediyor.
Dustin Poissant

$ ("# Single"). Tetikleyiciyi deneyin ({type: "change", val: "Single2"})
user2901633

44

Değişiklik olayını manuel olarak tetikleyebileceğinizi düşünüyorum trigger():

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

Neden otomatik olarak ateşlemese de, hiçbir fikrim yok.


Ben de, ($ # "# single"). Val ("Single2"). Change (); Dinamik olarak açılır liste oluşturuyorum ve değerini değiştiriyorum (Benim için iyi çalışıyor) Ama tetiklemeye çalıştığımda değişim benim için çalışmıyor.
Maneesh Kumar

4
Bir "bit" gecikti, ancak sonsuz döngülere yol açacağı için otomatik olarak ateşlenmiyor. Düşün$('#foo').change(function() { $( this ).val( 'whatever' ); });
JJJ

@Juhana Sonsuz bir döngü fark etmek, teşhis etmek ve düzeltmek val () gizemli bir şekilde "değişiklik" bağları tetiklemek için başarısız daha kolay olduğunu düşünüyorum.
iono

.Change () çağrısı, .trigger ('change') çağrısı için kısaltmadır.
Triynko

9

Bu kod parçasını val () işlevinden sonra eklemek işe yarıyor gibi görünüyor:

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

6
Evet, ancak bunun için ayrı bir DOM seçimi yapmanız gerekmez $(":input#single"). Aslında gerçekten yapmamalısın. Sadece zincirleyin .val(). Sen kullanabilir .trigger('change')ya .change(). Onlar tamamen aynı.
user113716

8

Bildiğim kadarıyla API'lerde okuyabilirim. Etkinlik yalnızca kullanıcı bir seçeneği tıkladığında tetiklenir.

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

Seçim kutuları, onay kutuları ve radyo düğmeleri için, kullanıcı fare ile bir seçim yaptığında olay hemen tetiklenir, ancak diğer öğe türleri için öğe öğe odağı kaybedene kadar ertelenir.


Diğer eleman tipleri için alternatifler nelerdir? 'Değişim' olayının input, öğe odağını kaybettiğinde değil, öğeler için hemen tetiklenmesini istiyorum. Biliyor musun?
Dan Nissenbaum

1
"Hemen" ile "girişte bir tuşa her basıldığında" demek istediğinizde, onkeyup, onkeypress ve onkeydown olaylarını arıyorsunuz, onchange değil.
user2867288

6

Daha kolay hale getirmek için özel bir işlev ekleyin ve değeri değiştirmenin de değişikliği tetiklemesini istediğinizde çağırın

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

ve

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

Veya val çağrıldığında her zaman değişikliği çağırmak için val işlevini geçersiz kılabilirsiniz

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

Numune http://jsfiddle.net/r60bfkub/


Tarayıcım çok fazla tekrarlamadan şikayet ediyor, bunun için herhangi bir düzeltme var mı?
Bhargav Nanekalva

change-Event'i bir denetim üzerinden dinliyorsunuz ve (doğrudan veya dolaylı olarak) changeaynı denetim üzerinde -event'i yeniden tetikleyen bir geri arama yürütüyorsunuz . Manuel olarak tetiklediğiniz olay için başka bir ad kullanmanızı öneririm (örn. explicit.change), Böylece change-event'i yeniden tetiklemez, döngüyü önler ve yine de olaya tepki vermenizi sağlar.
Kamafeather

3

Varsayılan değişiklik etkinliği ile karıştırmak istemiyorsanız özel etkinliğinizi sağlayabilirsiniz

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

değeri ayarlanan olayı tetiklemek için

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

3

Wordpress ile CMB2 kullanırken aynı sorunla karşılaştım ve bir dosya yükleme meta kutusunun change olayına kanca istedim.

Bu nedenle, değişikliği başlatan kodu (bu durumda CMB2 betiği) değiştiremiyorsanız, aşağıdaki kodu kullanın. Tetik, değer ayarlandıktan SONRA çağrılır, aksi takdirde change eventHandler'ınız çalışır, ancak değer ayarlanan değer değil, öncekidir.

İşte kullandığım kod:

(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);

Bu iyi, ancak bunu yalnızca belirli bir girdiyle nasıl sınırlandıracağınızı gösterebilir misiniz?
jwebb

@jwebb Ne demek istediğinizden emin değil misiniz? JQuery val () işlevini geçersiz kılıyoruz. Bir değişiklik olay işleyicisini belirli bir girdiye bağlarsınız.
user2075039

Yani, @ user2075039, jQuery val () işlevini kullanarak sayfada birden çok giriş varsa ve özel değişiklik olay işleyicisini TÜMÜ'ne değil, bunlardan sadece birine bağlamak istiyorsanız ne olur?
jwebb

@jwebb , belirli bir seçici için this.selectorgeçersiz kılma $.fn.valişlevi içinde kontrol edebilirsiniz (seçici için kullanılana bağlı olacaktır). Bu sadece belirli alanlar için bunu yapmak için bulduğum en iyisidir, tek sorun seçiciler için ne kullandıklarını
bilmelisiniz

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

Bu benim senaryom için çalıştı. 3 combos & chainSelect olayı ile bağladım, url ve varsayılan tüm açılır listeyi seçerek 3 değer geçmem gerekiyor. Bunu kullandım

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

Ve ilk olay işe yaradı.


10
Umarım bunu asla gerçek dünyada yapmazsın. $ _GET ['her ne olursa olsun'] güvenilir olamayacağını söylemeye gerek yok.
Denis V

1

Bir forma seçme seçeneğini yeni eklediyseniz ve change olayını tetiklemek istiyorsanız, bir setTimeout gerekli olduğunu fark ettim, aksi takdirde jQuery yeni eklenen seçme kutusunu almaz:

window.setTimeout(function() { jQuery('.languagedisplay').change();}, 1);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.