jQuery: aynı olay için birden fazla işleyici


137

İki olay işleyiciyi aynı öğe için aynı olaya bağlarsam ne olur?

Örneğin:

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

Son işleyici kazanır mı, yoksa her iki işleyici de çalışır mı?

Yanıtlar:


168

Her iki işleyici de çalışır, jQuery olay modeli bir öğe üzerinde birden fazla işleyiciye izin verir, bu nedenle daha sonraki bir işleyici eski bir işleyiciyi geçersiz kılmaz.

İşleyiciler, bağlı oldukları sırayla yürütülür .


1
yerel yolla ne olur? ve yerli kişi belirli bir tanesini nasıl kaldıracağını nasıl biliyor?
SuperUberDuper

1
DOM Seviye 3'e (referans olarak HTML 5 spesifikasyonu) göre, olay işleyicileri kaydedildikleri sırayla yürütülür - w3.org/TR/DOM-Level-3-Events/#event-phase ve w3.org/TR/ 2014 / REC-html5-20141028 /… . Olay işleyicileri, kayıtlı olan işleyiciye bir başvuru iletilerek kaldırılabilir
Russ Cam

@RussCam aynı işleyici daha sonra bağlı sonra ne olur jQuery('.btn').on('click',handlerClick);aslında herhangi bir şekilde aslında olmadan çeşitli yerlerde denir .offdiyelim?
techie_28

JQueryUI widgetfactory widget'ları için, işleyiciyi bir seçenek olarak ayarlarsanız bunun doğru olmadığını unutmayın. Hem eski hem de yeni işleyicinin çağrılması için bindyöntemi kullanmanız gerekir . Ayrıntılar için buna bakın: learn.jquery.com/jquery-ui/widget-factory/…
Michael Scheper

@MichaelScheper cevabı düzenlemek ve ek bilgi ile güncellemekten çekinmeyin
Russ Cam

36

F ve g olmak üzere iki işleyiciniz olduğunu ve bunların bilinen ve sabit bir sırada yürütüldüğünden emin olmak istediğinizi varsayalım, sadece bunları kapsülleyin:

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

Bu şekilde (jQuery perspektifinden) , belirtilen sırayla f ve g'yi çağıran yalnızca bir işleyici vardır .


3
+1, bir fonksiyon içindeki kapsülleme yoludur. Ve tetiklenen olayı / olayları kontrol etmek için işleyici fonksiyonunun içinde daha da iyi koşullu mantık bulunabilir.
Gordon Potter

Dizisi programlı olarak belirlenen işleyiciler koleksiyonu.
Aaron Blenkush

17

jQuery's .bind (), bağlı olduğu sırada açılır :

Bir olay bir öğeye ulaştığında, öğe için o olay türüne bağlı tüm işleyiciler tetiklenir. Kayıtlı birden çok işleyici varsa, bunlar her zaman bağlı oldukları sırayla yürütülür. Tüm işleyiciler yürütüldükten sonra, olay normal olay yayılma yolu boyunca devam eder.

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

JQuery'nin diğer işlevleri (ör. .click()) Kısayolları olduğu için .bind('click', handler), bağlı oldukları sırada da tetiklendiklerini tahmin ediyorum.


11

Olayları sırayla yürütmek için zincirleme kullanabilmeniz gerekir, örneğin:

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

Aşağıdaki kod aynı yapıyor sanırım

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

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

TFM ayrıca şunları söylüyor:

Bir olay bir öğeye ulaştığında, öğe için o olay türüne bağlı tüm işleyiciler tetiklenir. Kayıtlı birden çok işleyici varsa, bunlar her zaman bağlı oldukları sırayla yürütülür. Tüm işleyiciler yürütüldükten sonra, olay normal olay yayılma yolu boyunca devam eder.


1
Ne kod ne de bu makale, işleyici yürütme sırasını tanımlamaz. Evet, olay bağlamanın gerçekleşeceği sıra, ancak olay işleyicilerinin çağırdığı sıra hala resmi olarak tanımlanmamıştır.
Crescent Fresh

ehh? "Şimdi click olayı gerçekleştiğinde, ilk olay işleyicisi çağrılır, ardından ikincisi ardından üçüncüsü gelir." belirsiz mi?
anddoutoi

ve evet, resmi recs bunu tanımlamak biliyorum ve PPK zaten olay yürütme rastgele olduğunu kanıtladı ama belki jQuery bu düzeltti ^ ^
anddoutoi 29:09

Ahh, bu cümleyi kaçırdı. Aslında, yazar yanlış bilgilendirilmiştir. jQuery bunu "düzeltmedi". Spesifikasyon siparişi resmi olarak tanımlamadığından, teknik olarak hiçbir şeyin düzeltilmesi gerekmez.
Crescent Fresh

5
@CrescentFresh: Böyle geç bir cevap için özür dilerim, sadece soruyu gördüm, ancak bağlantı vermenizi istiyorum , When 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.
jQuery'nin


2

Stephan202'nin enkapsülasyonu ve çoklu olay dinleyicileri kullanılarak başarılı bir şekilde çalışmasını sağladı 3 arama sekmesi var, bir Array giriş metin kimlikleri tanımlayalım:

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

Searchtab1 içeriği değiştiğinde, searchtab2 ve searchtab3'ü güncellemek istiyorum. Kapsülleme için şu şekilde mi:

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

Birden fazla olay dinleyicisi:

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

Her iki yöntemi de seviyorum, ancak programcı kapsüllemeyi seçti, ancak çoklu olay dinleyicileri de çalıştı. Test etmek için Chrome'u kullandık.


1

Bir işleyicinin birbiri ardına gerçekleşmesini garanti etmek için bir geçici çözüm vardır: ikinci işleyiciyi içeren bir elemana takın ve olayın kabarmasına izin verin. Konteynere bağlı işleyicide event.target'a bakabilir ve ilgilendiğiniz bir şey yapabilirsiniz.

Kaba, belki, ama kesinlikle işe yaramalı.


0

jquery, birden çok olay işleyicisine izin verdiği için her iki işleyiciyi de yürütür. Örnek kod oluşturdum. Deneyebilirsin

gösteri

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.