val () tidak memicu perubahan () di jQuery


343

Saya mencoba memicu changeacara pada kotak teks ketika saya mengubah nilainya dengan tombol, tetapi tidak berhasil. Periksa biola ini .

Jika Anda mengetik sesuatu di kotak teks dan mengklik di tempat lain, changedipicu. Namun, jika Anda mengklik tombol, nilai kotak teks berubah, tetapi changetidak memicu. Mengapa?



Judul sendiri menjawab pertanyaan saya. Dikonfirmasi pada .change () yellow "Catatan: Mengubah nilai elemen input menggunakan JavaScript, menggunakan .val () misalnya, tidak akan memecat acara."
Bob Stein

Seandainya saya menemukan stackoverflow.com/questions/11873721/… lebih cepat, semoga membantu.
JeopardyTempest

Jawaban:


454

onchange hanya menyala saat pengguna mengetik ke input dan kemudian input kehilangan fokus.

Anda dapat memanggil onchangeacara secara manual menggunakan setelah menetapkan nilainya:

$("#mytext").change(); // someObject.onchange(); in standard JS

Atau, Anda dapat memicu acara menggunakan:

$("#mytext").trigger("change");

18
jangan ragu untuk memperluas jquery dan menambahkan fungsi valWithChange yang akan melakukan apa yang Anda inginkan. Tidak boleh tindakan default karena Anda tidak ingin peristiwa memicu dari perubahan nilai otomatis, hanya saat pengguna berinteraksi dengan elemen
redsquare

8
Saya ingin melihat jawaban ini diedit untuk membahas opsi rantai .change()ke .val()metode.
Snekse

19
Alasannya mungkin bahwa beberapa orang menyebutnya .val()di .change()karena mereka melakukan validasi input. Memicu .change()aktif .val()akan menyebabkan loop tak terbatas.
yingted

7
Hanya jika mereka mengubah nilai menjadi sesuatu yang akan gagal validasi mereka sendiri, yang akan konyol.
Leng

3
Saya akhirnya mengikat untuk blurmencapai sesuatu yang serupa:$('#mytext').focus().val('New text').blur();
Wes Johnson

63

Dari saran redsquare yang sangat bagus, ini bekerja dengan baik:

$.fn.changeVal = function (v) {
    return this.val(v).trigger("change");
}

$("#my-input").changeVal("Tyrannosaurus Rex");

5
Anda tidak perlu membungkus this:return this.val(v).trigger("change");
Mr. Polywhirl

27

Anda dapat dengan mudah mengganti valfungsi untuk memicu perubahan dengan menggantinya dengan proksi ke valfungsi asli .

cukup tambahkan kode ini di suatu tempat di dokumen Anda (setelah memuat jQuery)

(function($){
    var originalVal = $.fn.val;
    $.fn.val = function(){
        var result =originalVal.apply(this,arguments);
        if(arguments.length>0)
            $(this).change(); // OR with custom event $(this).trigger('value-changed');
        return result;
    };
})(jQuery);

Contoh kerja: di sini

(Perhatikan bahwa ini akan selalu memicu changeketika val(new_val)dipanggil bahkan jika nilainya tidak benar-benar berubah.)

Jika Anda ingin memicu perubahan SAJA ketika nilainya benar-benar berubah, gunakan yang ini:

//This will trigger "change" event when "val(new_val)" called 
//with value different than the current one
(function($){
    var originalVal = $.fn.val;
    $.fn.val = function(){
        var prev;
        if(arguments.length>0){
            prev = originalVal.apply(this,[]);
        }
        var result =originalVal.apply(this,arguments);
        if(arguments.length>0 && prev!=originalVal.apply(this,[]))
            $(this).change();  // OR with custom event $(this).trigger('value-changed')
        return result;
    };
})(jQuery);

Contoh langsung untuk itu: http://jsfiddle.net/5fSmx/1/


4
Hmm, tambalan bebek yang tidak perlu, saya pikir :-p. Mungkin lebih baik, seperti dikomentari oleh redsquare , memberikan fungsi yang berbeda nama .val().
binki

1
Jika Anda mengganti nama, Anda harus mengubah kode yang ada - dengan cara ini kode Anda yang ada akan terus bekerja
Yaron U.

4
Tetapi kemudian semua kode yang ditulis dengan definisi yang benar .val()dalam pikiran tiba-tiba akan mulai menghasilkan efek samping :-p.
binki

2
Ini juga akan membuat kerusakan plugin, yang mungkin tidak mudah diperbaiki
SoWhat

1
Untuk menghindari efek samping, saya memodifikasi fungsi val seperti di atas, tetapi saya memicu peristiwa berbeda ("val"), yang memungkinkan saya menyimpan kode yang ada tetapi dengan mudah menanganinya kapan pun saya perlu: $ (... ) .pada ('ganti val', ...)
ulu


14

Tidak, Anda mungkin perlu memicunya secara manual setelah menetapkan nilai:

$('#mytext').change();

atau:

$('#mytext').trigger('change');

8

Sepertinya acara tidak menggelegak. Coba ini:

$("#mybutton").click(function(){
  var oldval=$("#mytext").val();
  $("#mytext").val('Changed by button');
  var newval=$("#mytext").val();
  if (newval != oldval) {
    $("#mytext").trigger('change');
  }
});

Saya harap ini membantu.

Saya mencoba hanya tua biasa $("#mytext").trigger('change')tanpa menyimpan nilai lama, dan .changeapi bahkan jika nilainya tidak berubah. Itu sebabnya saya menyimpan nilai sebelumnya dan dipanggil $("#mytext").trigger('change')hanya jika itu berubah.


Terkejut ini tidak memiliki suara lebih banyak, karena ini adalah implementasi perubahan elemen HTML yang efektif saat ini.
vol7ron

4

Pada Februari 2019 .addEventListener()saat ini tidak berfungsi dengan jQuery .trigger()atau .change(), Anda dapat mengujinya di bawah ini menggunakan Chrome atau Firefox.

txt.addEventListener('input', function() {
  console.log('not called?');
})
$('#txt').val('test').trigger('input');
$('#txt').trigger('input');
$('#txt').change();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="txt">

Anda harus menggunakan .dispatchEvent()gantinya.

txt.addEventListener('input', function() {
  console.log('it works!');
})
$('#txt').val('yes')
txt.dispatchEvent(new Event('input'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input type="text" id="txt">


1

Dari https://api.jquery.com/change/ :

The changeevent dikirim ke elemen ketika nilainya berubah. Acara ini terbatas pada <input>elemen, <textarea>kotak , dan <select>elemen. Untuk kotak pilih, kotak centang, dan tombol radio, acara tersebut dipecat segera ketika pengguna membuat pilihan dengan mouse, tetapi untuk jenis elemen lainnya acara ditunda sampai elemen kehilangan fokus.


1

Saya tahu ini adalah utas lama, tetapi bagi yang lain mencari, solusi di atas mungkin tidak sebagus yang berikut ini, daripada memeriksa changeacara, periksa inputacara.

$("#myInput").on("input", function() {
    // Print entered value in a div box
    $("#result").text($(this).val());
});
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.