jQuery: lebih dari satu penangan untuk acara yang sama


137

Apa yang terjadi jika saya mengikat dua penangan kejadian ke acara yang sama untuk elemen yang sama?

Sebagai contoh:

var elem = $("...")
elem.click(...);
elem.click(...);

Apakah pawang terakhir "menang", atau apakah kedua pawang akan lari?

Jawaban:


170

Kedua penangan akan berjalan, model peristiwa jQuery memungkinkan beberapa penangan pada satu elemen, oleh karena itu penangan selanjutnya tidak menggantikan penangan yang lebih lama.

Pawang akan mengeksekusi sesuai urutan mereka terikat .


1
apa yang terjadi dengan cara asli? dan bagaimana penduduk asli tahu cara menghapus yang spesifik?
SuperUberDuper

1
Menurut DOM Level 3 (mereferensikan spesifikasi HTML 5), pengendali acara dijalankan sesuai urutan pendaftarannya - w3.org/TR/DOM-Level-3-Events/#event-phase dan w3.org/TR/ 2014 / REC-html5-20141028 /… . Penangan acara dapat dihapus dengan memberikan referensi ke penangan yang telah terdaftar
Russ Cam

@RussCam apa yang terjadi jika penangan yang sama terikat lebih dari satu kali katakan saja jQuery('.btn').on('click',handlerClick);dipanggil di berbagai tempat tanpa benar-benar di .offmana pun?
techie_28

Perhatikan bahwa untuk widget widgetfactory jQueryUI, ini tidak benar jika Anda menyetel penangan sebagai opsi. Agar penangan lama dan baru dipanggil, Anda perlu menggunakan bindmetode ini. Lihat ini untuk detailnya: learn.jquery.com/jquery-ui/widget-factory/…
Michael Scheper

@MichaelScheper merasa bebas untuk mengedit jawaban dan memperbarui dengan info tambahan
Russ Cam

36

Misalkan Anda memiliki dua penangan, f dan g , dan ingin memastikan bahwa mereka dieksekusi dalam urutan yang diketahui dan tetap, maka rangkum saja:

$("...").click(function(event){
  f(event);
  g(event);
});

Dengan cara ini (dari perspektif jQuery) hanya ada satu penangan, yang memanggil f dan g dalam urutan yang ditentukan.


3
+1, enkapsulasi di dalam suatu fungsi adalah cara yang harus dilakukan. Dan logika kondisional yang lebih baik dapat dimasukkan di dalam fungsi handler untuk mengontrol kejadian yang dipicu.
Gordon Potter

Kumpulan penangan yang urutannya ditentukan secara terprogram.
Aaron Blenkush

17

.bind () jQuery diaktifkan dalam urutan itu terikat :

Ketika sebuah kejadian mencapai sebuah elemen, semua penangan yang terikat ke tipe kejadian untuk elemen tersebut akan diaktifkan. Jika ada beberapa penangan yang terdaftar, mereka akan selalu mengeksekusi sesuai urutan mereka terikat. Setelah semua penangan dijalankan, acara berlanjut di sepanjang jalur penyebaran acara normal.

Sumber: http://api.jquery.com/bind/

Karena fungsi jQuery yang lain (mis. .click()) Adalah pintasan .bind('click', handler), saya kira fungsi-fungsi itu juga dipicu dalam urutan mengikatnya.


11

Anda harus bisa menggunakan chaining untuk mengeksekusi event secara berurutan, misalnya:

$('#target')
  .bind('click',function(event) {
    alert('Hello!');
  })
  .bind('click',function(event) {
    alert('Hello again!');
  })
  .bind('click',function(event) {
    alert('Hello yet again!');
  });

Saya kira kode di bawah ini melakukan hal yang sama

$('#target')
      .click(function(event) {
        alert('Hello!');
      })
      .click(function(event) {
        alert('Hello again!');
      })
      .click(function(event) {
        alert('Hello yet again!');
      });

Sumber: http://www.peachpit.com/articles/article.aspx?p=1371947&seqNum=3

TFM juga mengatakan:

Ketika sebuah kejadian mencapai sebuah elemen, semua penangan yang terikat ke tipe kejadian untuk elemen tersebut akan diaktifkan. Jika ada beberapa penangan yang terdaftar, mereka akan selalu mengeksekusi sesuai urutan mereka terikat. Setelah semua penangan dijalankan, acara berlanjut di sepanjang jalur penyebaran acara normal.


1
Baik kode itu maupun artikel itu tidak menentukan urutan eksekusi penangan. Ya, itulah urutan event binding akan terjadi, tetapi urutan yang dipanggil oleh event handler masih belum ditentukan secara resmi.
Crescent Fresh

ehh? bagaimana dengan "Sekarang saat event klik terjadi, event handler pertama akan dipanggil, diikuti oleh yang kedua, diikuti oleh yang ketiga." tidak jelas?
anddoutoi

dan ya, saya tahu bahwa rekomendasi resmi tidak mendefinisikan ini dan PPK telah membuktikan bahwa pelaksanaan acara itu acak tetapi mungkin jQuery telah memperbaikinya ^^
anddoutoi

Ahh, melewatkan kalimat itu. Faktanya, penulis salah informasi. jQuery belum "memperbaiki" ini. Karena spesifikasi tidak secara resmi menentukan pesanan, secara teknis tidak ada yang perlu diperbaiki.
Crescent Fresh

5
@CrescentFresh: Maaf atas jawaban yang terlambat, saya baru saja melihat pertanyaannya, tetapi saya ingin Anda menunjukkan tautannya , ini adalah dokumentasi resmi jQuery dan dengan jelas mengatakan bahwaWhen an event reaches an element, all handlers bound to that event type for the element are fired. If there are multiple handlers registered, they will always execute in the order in which they were bound. After all handlers have executed, the event continues along the normal event propagation path.
Razort4x

2

Kedua penangan dipanggil.

Anda mungkin berpikir tentang pengikatan acara inline (misalnya "onclick=..."), di mana kelemahan besar hanya satu penangan yang dapat ditetapkan untuk sebuah acara.

jQuery sesuai dengan model registrasi event DOM Level 2 :

Model Peristiwa DOM memungkinkan pendaftaran beberapa event listener pada satu EventTarget. Untuk mencapai ini, event listener tidak lagi disimpan sebagai nilai atribut


@ Kaya: urutan secara resmi belum ditentukan.
Crescent Fresh

2

Berhasil berhasil menggunakan 2 metode: enkapsulasi Stephan202 dan beberapa event listener. Saya memiliki 3 tab pencarian, mari kita tentukan id teks masukan mereka dalam Array:

var ids = new Array("searchtab1", "searchtab2", "searchtab3");

Ketika konten searchtab1 berubah, saya ingin memperbarui searchtab2 dan searchtab3. Lakukan dengan cara ini untuk enkapsulasi:

for (var i in ids) {
    $("#" + ids[i]).change(function() {
        for (var j in ids) {
            if (this != ids[j]) {
                $("#" + ids[j]).val($(this).val());
            }
        }
    });
}

Beberapa pendengar acara:

for (var i in ids) {
    for (var j in ids) {
        if (ids[i] != ids[j]) {
            $("#" + ids[i]).change(function() {
                $("#" + ids[j]).val($(this).val());
            });
        }
    }
}

Saya suka kedua metode tersebut, tetapi programmer memilih enkapsulasi, namun pendengar beberapa acara juga bekerja. Kami menggunakan Chrome untuk mengujinya.


1

Ada solusi untuk menjamin bahwa satu penangan terjadi setelah penangan lainnya: pasang penangan kedua ke elemen penampung dan biarkan acara menggelembung. Di penangan yang dilampirkan ke penampung, Anda dapat melihat event.target dan melakukan sesuatu jika itu yang Anda minati.

Kasar, mungkin, tapi pasti berhasil.


0

jquery akan mengeksekusi kedua handler karena memungkinkan banyak event handler. Saya telah membuat kode contoh. Kamu bisa mencobanya

demo

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.