.on() Metodu

.on( events [, selector ] [, data ], handler ) Dönen Değer : jQuery Nesnesi
Açıklama : Seçilen elemanlara bir ya da daha fazla olay işleyici bağlar.

.on( events [, selector ] [, data ], handler )
events
Tip : String
Bir ya da boşluklarla ayrılmış daha fazla olay tipi adını ve varsa nameSpace değeri içeren string. "click" veya "keydown.myPlugin" gibi.
selector
Tip : String
Seçilmiş elemanların olayı tetikleyen alt elemanlarını bulmak için seçici filtre. Bu değer null ise ya da verilmemişse olay seçili elemanda tetiklenir.
data
Tip : Herhangi bir şey
Olay işleyiciye event.data olarak kullanması için gönderilecek veri.
handler
Tip : Fonksiyon( Olay eventObject [, Herhangi birşey extraParameter ] [, ... ] )
Olay her tetiklendiğinde çalıştırılacak olan fonksiyon. Sadece return false; içeriğine sahip bir fonksiyon yerine direk buraya false değer verilebilir.


.on( events [, selector ] [, data ] )
events
Tip : Düz Nesne
Key olarak bir ya da boşluklarla ayrılmış daha fazla olay tipi adını içeren string ve value olarak olay işleyici fonksiyon içeren nesne.
selector
Tip : String
Seçilmiş elemanların olayı tetikleyen alt elemanlarını bulmak için seçici filtre. Bu değer null ise ya da verilmemişse olay seçili elemanda tetiklenir.
data
Tip : Herhangi bir şey
Olay işleyiciye event.data olarak kullanması için gönderilecek veri.


.on() metodu jQuery nesnesi olarak seçilmiş elemanlara olay işleyiciler bağlamak için kullanılır. Eski versiyon jQuery olay metodlarından dönüştürmeye yardımcı olarak, .bind(), .delegate() ve .live() metodlarına bakınız. .on() ile bağlanan olayları iptal etmek için .off() metoduna bakınız. Bir kere çalışan ve kendini iptal eden olay işleyici için .one() metoduna bakınız.


Olay İsimleri ve Namespace

events parametresinde herhangib olay ad(lar)ı verilebilir. JQuery bunları standart JavaScript olay tiplerine eşleştirir, daha sonra tarayıcının tetiklediği olaya karşılık (mesela click olayı) handler olarak verilen olay işleyici çağrılır. Ayrıca .trigger() metodu da tarayıcı standart olaylarını ve kullanıcı tanımlı olayları tetikleyebilir ve olay işleyicilerini çağırabilir. Olay isimleri sadece alfanümerik karakterler, alt çizgi ve iki nokta üstüste içerebilir.

Bir olay ismi bir event namespace ile gruplanabilir. Böylece olayların iptal edilmesi ve tetiklenmesi kolaylaşır. Örneğin "click.myPlugin.simple" değeri click olayını hem myPlugin hem simple namespace'i üyesi yapar. Bu değerle elemana tanımlanan click olayı işleyicisi, aynı elemana bağlı diğer click olay işleyicilerine dokunmadan .off("click.myPlugin") ya da .off("click.simple") kodları ile iptal edilebilir. Namespace'ler CSS class değerlerine benzerler, hiyerarşik yapı değildirler sadece adlarının eşleşmesi yeterlidir. Namespace değerlerinde sadece büyük-küçük harf ve sayılar olabilir.

İkinci .on() metodu kullanım şeklinde events parametresi bir düz nesnedir. Key değerleri string olan events parametresi gibi bağlanacak olay ya da olayların adını varsa namespace ile birlikte içerir. Value değerlerinde ise key değerinde verilen olaya karşı çalışması istenen olay işleyici fonksiyon (ya da false) girilir, bu kullanım şeklinde .on() metoduna handler parametresi ile olay işleyici verilmez. Diğer açılardan bu iki kullanım şekkli aşağıda anlatıldığı şekilde aynı davranırlar.


Direk ve Delegasyonlu Olay İşleyiciler

Tarayıcı olaylarının büyük çoğunluğu olayın bağlandığı en içerdeki elemandan ( event target ) üst elemanlara yayılarak en üstteki document nesnesine kadar iletilir. IE8 ve öncesinde change ve submit üste doğru yayılmaz ama jQuery bunları da tarayıcılar arası uyum için üste yayar.

Eğer selector parametresi verilmemiş ya da null değer verilmişse, bu olaya direk ya da direk bağlanmış olay denir. Seçilmiş olan elemanlarda olay o elemanın kendisinde oluştuğunda ya da içindeki elemanlardan birinde oluşup ona kadar yayılarak geldiğinde verilen olay işleyici fonksiyon çalışır.

Eğer selector parametresinde bir seçici deyim verilmişse, buna delegasyonlu olay denir. Seçili elemanda direk oluşan olay işe yaramaz, sadece seçici deyimle eşleşen içindeki elemanlardan birinde olay oluşur ve yayılarak seçili elemana gelirse olay işleyici çalışır. JQuery selector parametresi ile belirtilen elemanlardan olay işleyicinin tanımlandığı üst elemana kadar olayın yayılmasını sağlayacaktır (en içteki elemandan en dıştaki elemana kadar).

Olay işleyiciler sadece seçili olan elemanlara bağlanır; .on() metodunu çağırdığınız anda sayfada bu elemanlar mevcut olmalıdır. Elemanların mevcut olduğu ve seçilmiş olduğundan emin olmak için ya HTML kodunda elemanların arkasından script'inizi koyun ya da document.ready olay işleyicisi içine yerleştirin (ki çoğu zaman böyle yapılır). Sonradan gelecek elemanlar için delegasyon yoluyla olay işleyici ekleme alternatifi kullanılabilir.

Delegasyonlu olay işleyicileri seçili eleman içinde daha sonra eklenecek elemanlarda da kullanılabilmesi avantajına sahiptir. Bir sayfada sıklıkla eklenen ya da çıkarılan elemanlar ve bu elemanlarda olmasını istediğiniz olaylar varsa elemanları her zaman mevcut olan bir dış eleman içinde toplayarak delegasyonlu olay işleyicisi kullanmak işinizi kolaylaştırır. Örneğin dinamik içerikli MVC (model-view-controller) yapıdaki sayfalarda görseller hep bir dış konteyner eleman içinde verilere göre değişir, bu konteyner seçilebilr. document elemanı da sayfaya hiç bir HTML eleman yüklemeden önce <head> kısmında hazırdır ve erişilebilir, sonradan gelecek elemanlar için olay işleyicileri document nesnesi üzerinden de delegasyonlu bağlayabilirsiniz.

Delegasyonlu olay işleyici bağlamak sadece sonradan gelecek elemanlara olay işleyici bağlamak dışında sayfadaki bir sürü benzer olayı takip etmenizi de kolaylaştırır. Örneğin 1000 satırlı bir tbody elemanında her bir satıra olay işleyici eklenmesi.

$( "#dataTable tbody tr" ).on( "click", function() {
  console.log( $( this ).text() );
});

Bu kod tüm <tr> elemanlarına direk olarak bir olay işleyici bağlar. Halbuki sadece <tr> elemanından <tbody> elemanına yayılarak geçen bir tıklama olayına tek bir olay işleyici tanımlanabilir.

$( "#dataTable tbody" ).on( "click", "tr", function() {
  console.log( $( this ).text() );
});

Not : Delegasyonlu olay işleyiciler SVG için çalışmaz.


Olay İşleyici ve Onun Ortamı

handler parametresi bir fonksiyondur (ya da bazı durumlarda aşağıda görüleceği üzere false değer) ve eğer events parametresinde nesne içinde verilmiyorsa bu parametreye girilmesi gerekir. Parametrede bir anonim fonksiyon olarak girilebildiği gibi isimli bir fonksyonun adı da girilebilir.

function notify() {
  alert( "tıklandı" );
}
$( "button" ).on( "click", notify );

Tarayıcı bir olayı tetiklediğinde ya da JavaScript kod içinde .trigger() metodu yardımıyla olay tetiklendiğinde, jQuery olay işleyiciye Event nesnesini parametrede gönderir ve bu nesne olayı incelemek ya da işlemek amacıyla fonksiyon içinde kullanılabillir. Bu nesne tarayıcı tarafından verilen değerlerin düzenlenmiş bir halidir. Tarayıcının işlenmemiş ham event nesnesi event.originalEvent özelliğinde bulunur. Örneğin event.type içinde olayın adı vardır ("resize" gibi) ve event.target olayın oluştuğu en içteki elemanı verir.

Default davranış olarak orjinal olay elemanından document nesnesine kadar olay yayılarak gider. Yol üzerindeki tüm elemanlarda eşleşen olay versa jQuery hepsini işleyecektir. Bunlardan birinde olayın yukarı doğru yayılmasını engelleyen event.stopPropagation() kodu girilerek dökümana kadar olayın yayılması engellenebilir. Bununla beraber bulunulan elemandaki aynı olaya bağlanan diğer olay işleyiciler çalışacaktır. Bunu da engellemek isterseniz event.stopImmediatePropagation() metodu kullanırsınız. Aynı eleman aynı olaya bağlı olay işleyiciler, tanımlama kodlarının işlenme sırasına göre çağrılır yan bilgisini de verelim.

Benzer olarak bir olay işleyici söz konusu elemanın tarayıcıdaki default davranışını da event.preventDefault() ile engelleyebilir, örneğin linke tıklanınca hedefe giden click olayı gibi. Tüm tarayıcı olayları default davranışa sahip değildir ve tüm default davranışlar da iptal edilemez. Bu konuda detay için W3C Events Specification sayfasına bakınız.

Bir olay işleyiciden false dönerek otomatik olarak event.stopPropagation() ve event.preventDefault() çağrılması sağlanır. Kısaltma olarak handler değerine function(){ return false; } kodu yerine direk false da yazılabilir. Yani $( "a.disabled" ).on( "click", false ); kodu disabled class değerine sahip tüm linklerin aksiyonunu engellediği gibi tıklamanın üst elemanlara doğru yayılmasını da engeller.

JQuery bir olay işleyiciyi çağırdığında this kelimesi olayın tanımlandığı elemanı içerir. Direk bağlanan elemanlar için bu eleman olayın bağlandığı elemandır, delegasyonlu tanımlamalarda ise selector ile olay dinlemesi yapılan elemandır. (Not, eğer olay iç elemanlardan yayılma ile geldiyse this ile event.target farklı olurlar). JQuery metodları ile birlikte kullanılabilecek bir jQuery nesnesi oluşturmak için $( this ) kodu kullanılabilir.


Olay İşleyiciye Veriler Göndermek

Eğer .on() metodunda data parametresi varsa ve değeri null ya da undefined değilse, olay her tetiklendiğinde buradaki veri olay işleyiciye event.data nesnesi ile verilir. data parametresi herhangi bir veri tipinde olabilir. Fakat eğer selector parametresinde string bir değer verilecekse data değerinin de ya verilmesi ya da null olarak belirtilmesi gerekir, böylece data ve selector karışmaz. En iyisi verileri düz nesne içinde vermektir.

Versiyon 1.4 ile aynı olay işleyici bir elemana defalarca bağlanabilir. Bu özellikle event.data kullanılacaksa faydalı olacaktır. Örneğin:

function greet( event ) {
   alert( "Hello " + event.data.name );
}
$( "button" ).on( "click", {
   name: "Karl"
}, greet );
$( "button" ).on( "click", {
   name: "Addy"
}, greet );

Yukarıdaki kod butona tıklanınca iki farklı alert mesajı verecektir.

.on() metodunda data ile veri göndermeye bir diğer alternatif ise .trigger() veya .triggerHandler() metodları kullanırken onlarla birlikte parametreleri göndermek. Bu yolla gönderilen veriler olay işleyici tanımında Event parametresi arkasından virgülle ayrılmış olarak verilen parametreler olarak olay işleyiciye geçerler. .trigger() ya da .triggerHandler() metodlarında ikinci parmetreye bir array verilirse, array'in her elemanı olay işleyiciye ilave bir parametre olarak gelecektir.


Olay Performansı

Bir çok durumlarda örneğin click gibi olaylar çok sık gerçekleşmez ve performans önemli bir sorun değildir. Bununla beraber mousemove ya da scroll gibi olaylar saniye içinde defalarca oluşabilir ve bu durumda olayları sağ duyulu bir şekilde ele almak önemli olur. Olay işleyici içinde yapılan işleri azaltarak performans arttırılabilir. Olay işleyiciye lazım olan bilgileri her sefer hesaplamak yerine cash etmek veya setTimeout ile sayfada yenileme sayılarını azaltmak gibi önlemler alınabilir.

Dökümanın en üst seviyesine yakın elemanlarda çok fazla sayıda delegasyonlu olay tanımlamak performansı düşürebilir. Olay her oluştuğunda jQuery olayın gerçekleştiği elemandan olay işleyiciyi tanımladığınız elemana kadar olayın yayılımını tek tek çalışır. En iyi performans için delegasyonlu olayları olayın gerçekleşeceği elemanlara en yakın üst elemanlarda tanımlayınız. Büyük dökümanlarda delegasyonlu olayları tanımlamak için document ya da document.body elemanlarını mümkün olduğunca az kullanınız.

JQuery tag#id.class şeklindeki basit seçici deyimleri çok hızlı işler. Bu durumda örn. "#myForm", "a.external" ve "button" çok hızlı seçicilerdir. Daha karmaşık seçiciler kullanan delegasyonlu olay tanımlarında özellikle hiyerarşik olanlar daha yavaş çalışır. Örneğin
$( "body" ).on( "click", "#commentForm .addNew", addComment ) yerine
$( "#commentForm" ).on( "click", ".addNew", addComment ) kullanmak daha yüksek performans sağlar.


İlave Notlar

Bazı olayların açıklamaları için özel sayfalar ver. Bunların listesi için Olaylar Kategorisi sayfasına bakabilirsiniz.

Versiyon 1.8'de kapatıldı, 1.9'da silindi : "hover" ismi "mouseenter mouseleave" isimlerinin kısa yolu olarak kullanıldı. Bununla iki olaya tek bir olay işleyici bağlanıyordu ve olay işleyici event.type değerini işleyerek olayın mouseenter mi, mouseleave mi olduğunu bulmalıydı. Bunu bir ya da iki fonksiyon tanımı alan sahte .hover() metodu ile karıştırmayınız.

JQuery olay sistemi DOM elemanına bir bağlı özellik içinde verilerin saklanabilmesine imkan olmasını kullanır. object, embed, ve applet elemanları data özellikleri almadığı için jQuery tarafından onlara olay işleyici bağlanmaz.

W3C bilgilerine göre focus ve blur olayları yukarı doğru yayılmaz (buble yapmaz). Fakat jQuery'de yayılması olan focusin ve focusout olaylarına sahiptir. Delegasyonlu olay işleyicilerde focus veya blur olay işleyicisi kullanılırsa jQuery bunları sırasıyla focusin ve focusout olaylarına bağlar. Daha net göstermek için yayılmalı olan olay isimlerini kullanınız.

Tüm tarayıcılarda load, scroll ve error olayları yukarı yayılmaz. IE8 ve öncesinde paste ve reset olayları yukarı yayılmaz. Bu olaylar delegasyonlu olarak tanımlanamaz, ancak direk elemana bağlanarak olay işleyici çalıştırılabilir.

window nesnesinin error olayı standart olmayan parametrelere ve dönen değerlere sahiptir. Bu yüzden jQuery tarafından desteklenmez, yerine window.onerror özelliğine direk bir olay işleyici fonksiyonu tanımı veriniz.

Bir elemanın olay işleyici listesi olay ilk oluştuğunda ayarlanır. Bulunulan elemana yeni olay işleyici eklemek veya olanı silmek ancak olay bir sonra oluştuğunda geçerli olur. Bir olaya ait aynı elemandaki başka olay işleyicileri hemen iptal etmek için event.stopImmediatePropagation() metodu kullanılabilir. Bu davranış W3C events specification standardına ters düşer. Bunu daha net anlamak için şu koda bakalım:

   var $test = $( "#test" );
   
   function handler1() {
      console.log( "handler1" );
      $test.off( "click", handler2 );
   }
   
   function handler2() {
      console.log( "handler2" );
   }
   
   $test.on( "click", handler1 );
   $test.on( "click", handler2 );

Olay işleyici handler1 içinde diğeri olan handler2 kapatılıyor olsa bile ilk tıklamada çalışır. Ancak 2. defa elemana tıklanınca handler2 olayı iptal edilmiş olur.


Örnekler:

Bir paragrafa tıklanınca içindeki yazıyı alert ile göster.

$( "p" ).on( "click", function() {
   alert( $( this ).text() );
});

Olay işleyiciye nesne olarak veri gönder.

function myHandler( event ) {
   alert( event.data.foo );
}
$( "p" ).on( "click", { foo: "bar" }, myHandler );

Formun gönderimini iptal et ve olayın yukarı yayılmasını (buble) false değer dönerek engelle.

$( "form" ).on( "submit", false );

Sadece elemanın default aksiyonunu .preventDefault() ile iptal et.

$( "form" ).on( "submit", function( event ) {
   event.preventDefault();
});

Formun göndermesini iptal etmeden olayın yukarı yayılmasını .stopPropagation() ile engelle.

$( "form" ).on( "submit", function( event ) {
   event.stopPropagation();
});

.trigger() metodundaki parametre ile olay işleyiciye veri gönder.

$( "div" ).on( "click", function( event, person ) {
   alert( "Hello, " + person.name );
});
$( "div" ).trigger( "click", { name: "Jim" } );

.trigger() metodunda verilen array elemanlarının olay işleyiciye ilave parametreler olarak verilmesi.

$( "div" ).on( "click", function( event, salutation, name ) {
   alert( salutation + ", " + name );
});
$( "div" ).trigger( "click", [ "Goodbye", "Jim" ] );

Tarayıcıda olmayan kullanıcı tanımlı olayı bağlamak ve tetiklemek.

<style>
   p { color: red; }
   span { color: blue; }
</style>

<p>Bu elemanda kullanıcı tanımlı olay var.</p>
<button>Olayı tetikle</button>
<span style="display:none;"></span>
 
<script>
   $( "p" ).on( "myCustomEvent", function( event, myName ) {
      $( this ).text( myName + ", merhaba!" );
      $( "span" ).stop()
         .css( "opacity", 1 )
         .text( "myName = " + myName )
         .fadeIn( 30 ).fadeOut( 1000 );
   });
   $( "button" ).click(function () {
      $( "p" ).trigger( "myCustomEvent", [ "John" ] );
   });
</script>

Bu elemanda kullanıcı tanımlı olay var.


Birçok olay işleyiciyi düz nesne kullanarak aynı anda bağla.

<style>
   .test {
      color: #000; padding: .5em;
      border: 1px solid #444;
   }
   .active { color: #f00; }
   .inside { background-color: aqua; }
</style>

<div class="test">test div</div>

<script>
   $( "div.test" ).on({
      click: function() {
         $( this ).toggleClass( "active" );
      }, mouseenter: function() {
         $( this ).addClass( "inside" );
      }, mouseleave: function() {
         $( this ).removeClass( "inside" );
      }
   });
</script>
test div

Herhangi bir paragrafa tıklanınca ondan sonraya yeni bir paragraf ekle. Dikkat ederseniz .on() metodunda olay body üzerinden delegasyonlu bağlanınca sonradan gelecek paragraflarda bile olay tanımlanmış oluyor.

<style>
   p {
      background: yellow;
      font-weight: bold;
      cursor: pointer;
      padding: 5px;
   }
   p.over { background: #ccc; }
</style>

<p>Bana tıkla!</p>
<span></span>

<script>
   var count = 0;
   $( "#test4" ).on( "click", "p", function() {
      $( this ).after( "<p>Yeni paragraf! " + (++count) + "</p>" );
      $( this ).addClass("over");
   });
</script>

Bana tıkla!


Her paragrafa tıklanınca içindeki yazıyı alert ile göster.

$( "body" ).on( "click", "p", function() {
   alert( $( this ).text() );
});

.preventDefault() metodu kullanarak sayfadaki linklerin default aksiyonunu iptal et.

$( "body" ).on( "click", "a", function( event ) {
   event.preventDefault();
});

Birçok olaya tek olay işleyici bağla - burada mouseenter ve mouseleave olayları.

$( "#cart" ).on( "mouseenter mouseleave", function( event ) {
   $( this ).toggleClass( "active" );
});

.

.