Duyuruyu Kapat
Facebook Gözat
Twitter Gözat

Olaylara Fonksiyon Atamak?

Konu, 'Javascript' kısmında timemrah tarafından paylaşıldı.

  1. timemrah

    timemrah Daimi Üye

    Kayıt:
    7 Mart 2010
    Mesajlar:
    918
    Beğenilen Mesajlar:
    14
    Meslek:
    Web Geliştirici
    Şehir:
    Tekirdağ / Çorlu
    Merhaba;

    Olaylara fonksiyon atamak her zaman tam olarak anlayamadığım bir konu. Bu sorduğum soru vesilesiyle de konunun detaylarını daha iyi kavrayabileceğimi düşünüyorum. Ben herhangi bir elementin bir olayına javascript ile fonksiyon atarken şu şekilde kod yazıyorum.


    1. document.getElementById("tag idsi").onmousedown=function(){ fonk1(); fonk2()... v.s. }
    veya her tarayıcı desteklemese de
    2. document.getElementById("tag idsi").setAttribute("onmousedown" , "fonk1(); fonk2()... v.s.");

    Asıl derdime geçmeden burada aklıma takılan bir şeyi sormam gerekiyor çünkü asıl derdime yardımcı olabilir.
    1. sırada gösterdiğim atamayı bazı yerlerde document.getElementById("tag idsi").onmousedown=fonk1; şeklinde görebiliyorum. Bu kullanım şeklinin farkı ve ne işe yaradığı hakkında düzgün bir bilgim yok. Beni bu konu hakkında aydınlatırsanız çok sevinirim. Ayrıca bu kullanım şekli ile olaya 2 ayrı fonksiyon atamasını beceremedim.

    Asıl derdime gelince;
    Ben herhangi bir tagın olaylarına atanan fonksiyonları her tarayıcıda olmasa da elde edebiliyorum. document.getElementById("tag idsi").getAttribute("olay"); Bu şekilde bir tagın olayına eski fonksiyonları bozmadan yeni bir fonksiyon daha eklemek durumunda kalırsam önce eski atanmış fonksiyonları getAttribute ile alıp üzerine yeni eklediğim fonksiyonu ekleyerek olaya atama yapıyorum.

    Ama bunu window 'un olaylarıyla pek becerebildiğim söylenemez. window.document.getAttribute("olay"); veya window.getAttribute("olay"); kodları atama yaptığım olaylardaki fonksiyonları bana vermiyor ve hata üretiyor. Halbuki window nesnesinin olaylarına bir çok fonksiyon ekleyip çıkarmama gerekebiliyor. Bunu nasıl becerebilirim.

    İlgilenen ve yazımı okuyan tüm arkadaşlara şimdiden teşekkür ederim...
     
  2. skacurt

    skacurt Â

    Kayıt:
    4 Ocak 2008
    Mesajlar:
    4,340
    Beğenilen Mesajlar:
    21
    Meslek:
    Küfeci
    Şehir:
    İstanbul
  3. gokhanweb

    gokhanweb Aktif Üye

    Kayıt:
    12 Ocak 2005
    Mesajlar:
    321
    Beğenilen Mesajlar:
    0
    Şehir:
    Mersin
    window.document.getAttribute("olay");
    bu document'in olay attribute'sine erişmeye çalışır. window'un değil. zaten window'un attribute'si olmaz. document'in de olmaz. attribute sadece html ve xml taglarının sahip oldukları verilerdir.

    attribute üzerinden olay yaratılmaz zaten. doğru bir yaklaşım değildir.

    ie için attachEvent ve detachEvent
    ff, chrome vs için addEventListener ve removeEventListener kullanmalısınız.

    yani
    window.document.getAttribute("olay");
    yerine
    window.addEvenListener ile olay ekleyeceksiniz.
    window.removeEventListener ile olay sileceksiniz.

    bir olaya doğrudan erişmek için ise
    window.onload, window.onclose, window.onresize gibi doğrudan olay adını yazarak erişmelisiniz.

    ilk sorununuza gelirsek:

    Kod:
    var fonk1 = function(){
         this.innerHTML = "içerik"
    };
    document.getElementById("tag idsi").onmousedown=fonk1;
    
    Kod:
    document.getElementById("tag idsi").onmousedown=function(){
         this.innerHTML = "içerik"
    };
    
    ikiside kullanılabilir. ama ilkinde fonk1'in kullanılmadan önce tanımlanması gerekir.
     
  4. wingless

    wingless Aktif Üye

    Kayıt:
    28 Mart 2011
    Mesajlar:
    412
    Beğenilen Mesajlar:
    0
    IE'de attach/DetachEvent olduğu doğru ama olay dilin farklılığından (JScript vs JavaScript) değil web API'ın farklılığından kaynaklanıyor. Yani addEventListener ECMA'nın JavaScript standardında değil, W3C'nin DOM standardında tanımlanmıştır.
     
  5. timemrah

    timemrah Daimi Üye

    Kayıt:
    7 Mart 2010
    Mesajlar:
    918
    Beğenilen Mesajlar:
    14
    Meslek:
    Web Geliştirici
    Şehir:
    Tekirdağ / Çorlu
    Tüm ilgilenen ve cevap veren arkadaşlara çok teşekkürler. Yazılarınız fazlasıyla sorularıma cevap oldu...
     
  6. timemrah

    timemrah Daimi Üye

    Kayıt:
    7 Mart 2010
    Mesajlar:
    918
    Beğenilen Mesajlar:
    14
    Meslek:
    Web Geliştirici
    Şehir:
    Tekirdağ / Çorlu
    Verdiğiniz cevaplar doğrultusunda size şimdilik 1 adet sorum olucak arkadaşlar;

    addEventListener("click", fonk ,false) şeklinde ekleme yaptığımız "fonk" adındaki fonksiyon argümanlı ise argümanlarını nasıl belirtebiliriz?
     
  7. gokhanweb

    gokhanweb Aktif Üye

    Kayıt:
    12 Ocak 2005
    Mesajlar:
    321
    Beğenilen Mesajlar:
    0
    Şehir:
    Mersin


    normalde bir fonksiyonu kendin tetikleyebildiğin için özel olarak argüman belirleyebiliyorsun. daha sonra argümanları fonksiyona tetiklerken gönderiyorsun.
    ancak burda fonksiyonu sen değil tarayıcı tetikliyor ve tarayıcın tetiklediği fonksiyona kendi argümanlarını gönderiyor. bu yüzden fonksiyonu yazarken tarayıcının göndereceği argümanlara göre yazmalısın. ie olay tetikleyicisi fonksiyona argüman göndermez.
    webkit, gecko temelli tarayıcılar (ff, chrome, konq.) ise event (olay) argümanını gönderir. bu bilgiler ışığında "fonk" isimli fonksiyon şöyle olmalıdır:

    Kod:
    var fonk = function(olay){
      if(typeof olay == "undefined") {
        olay = window.event; // burası internet explorer için yazıldı. ie'de olay tetiklecilerine argüman göndermez.
      }
      // diğer işlemler
    }
    
    ama html elementinin olay tetikleyicisinin argümanlarını kendin belirlemek istiyorsan onclick (ve ya diğerleri) attribute'ünün içeriği şu şekilde: "fonk(arg1, arg2, arg3)" kendin belirleyebilirsin.

    önceki mesajda setAttribute ile olay tetikleyicisine fonksiyon göndermenin doğru olmadığından bahsetmiştim. aslında bu yöntem doğruluktan ziyade yaklaşım olarak yanlıştır. çünkü attr ile belirleme yaparsan önceki belirlenmiş olaylara da müdahale etmiş olursun.
    addEventListener ya da attachEvent ile var olan fonksiyonlara dokunmadan yeni olay dinleyicisi eklersin. (istersen dokunabilirsin tabi)

    javascript ve dom'u doğru anlayabilmek için kapsamları iyi bilmen gerekir. kapsam bir nesnesin nerden erişlebilir olduğu konusudur.
     
  8. timemrah

    timemrah Daimi Üye

    Kayıt:
    7 Mart 2010
    Mesajlar:
    918
    Beğenilen Mesajlar:
    14
    Meslek:
    Web Geliştirici
    Şehir:
    Tekirdağ / Çorlu
    @Gökhan , açıklayıcı yazını olabildiğince anlamaya çalıştım. İlgin alakan için ayrıca teşekkürler.



    Bu dediğine göre ufak bir örnek üretebilirsek konuyu çok daha iyi kavrayacağım. Elbette bir örnekle kavrayamayacağımı düşünüyorsan beni mümkünse bir kaynağa yönlendirebilirsin.

    Düşünelimki elimizde fonk1(id,ad) adlı bir fonksiyon var ve biz bu fonksiyonu addEventListener ile "b1" id'li butonun "click" olayına atayacağız. Dediğine göre benim bu fonksiyonu atarken argümanları belirtme şansım yok. Tarayıcının gönderdiği kendi argümanları var. Öyleyse ben fonk1 'i nasıl tekrar düzenlemeliyim. Ne hale sokabilirim ki argümanlarını da kullanabileyim. Sonuçta fonksiyonlarımda argüman kullanmak zorundayım. Olayı nesne yönelimli kodlama ile dahamı rahat çözerim. Argümanları nesneyi yaratıp belirtirim. Daha sonra nesneyi addEventListener ile olaya ekleyip kullanırım.

    Saçmalıyorsam kusuruma bakma aklıma başka bir şey gelmedi...
     
  9. timemrah

    timemrah Daimi Üye

    Kayıt:
    7 Mart 2010
    Mesajlar:
    918
    Beğenilen Mesajlar:
    14
    Meslek:
    Web Geliştirici
    Şehir:
    Tekirdağ / Çorlu
    Sanırım illa argümanlı bir fonksiyonu bu şekilde kullanacaksam nesne olarak kullanmam ve argümanları nesnenin değişkenleri şeklinde atamalar yaparak çözümleyebilirim.
     
  10. skacurt

    skacurt Â

    Kayıt:
    4 Ocak 2008
    Mesajlar:
    4,340
    Beğenilen Mesajlar:
    21
    Meslek:
    Küfeci
    Şehir:
    İstanbul
    Haklısın, teşekkür ederim.
    @timemrah tahmin ettiğin gibi yapılabileceği gibi bir diğer yol da şöyle : http://jsfiddle.net/nC6rt/
     
  11. gokhanweb

    gokhanweb Aktif Üye

    Kayıt:
    12 Ocak 2005
    Mesajlar:
    321
    Beğenilen Mesajlar:
    0
    Şehir:
    Mersin
    evet söylediğiniz şekilde de olur. yaklaşım olarak yine doğru olmaz. çünkü siz bir nesne yaratırsanız o nesneye varsayılan olarak kendini yaratan nesnenin bazı değerleri eklenir (bkz: Object.prototype).
    olması gereken yöntem kapsama alma yöntemidir. google'da javascript closures diye aratırsanız bir çok kaynağa ulaşabilirsiniz. ben bir tane örnek vereyim.

    Kod:
    function bilgi(ad, soyad, yas){
        alert("Ad: "+ad+"\nSoyad: "+soyad+"\nYaş: "+yas);
    }
    
    bunu click'e atamak istersek:
    Kod:
    var x = "Time", y = "Emrah", z = "25";
    eleman.addEventListener("click", bilgi(x, y, z), false);
    
    bu şekilde yapmak yanlış tabi.

    olması gereken şöyle:
    Kod:
    eleman.addEventListener("click",function(){
        var x = "Time", y = "Emrah", z = "25";
        return function(){
            bilgi(x, y, z);
        }
    }(), false);
    
     
  12. timemrah

    timemrah Daimi Üye

    Kayıt:
    7 Mart 2010
    Mesajlar:
    918
    Beğenilen Mesajlar:
    14
    Meslek:
    Web Geliştirici
    Şehir:
    Tekirdağ / Çorlu
    Konuya bakmayalı epey oldu. Cevaplarınızı ancak gördüm.

    @skacurt, @gokhanweb, @wingless;
    Açtığım Konuya ilginiz, alakanız ve cevaplarınızdan dolayı çok teşekkürler. Bu kadar açıklamalarınızdan sonra anlamamak elde değil...
     
  13. timemrah

    timemrah Daimi Üye

    Kayıt:
    7 Mart 2010
    Mesajlar:
    918
    Beğenilen Mesajlar:
    14
    Meslek:
    Web Geliştirici
    Şehir:
    Tekirdağ / Çorlu
    Bu örnek beni büyük bir araştırma uğraşından kurtardı diyebilirim. Gerçekten de Javascrip'tin kodlarının ne zaman nasıl çalıştığına dair süper bir örnek. Şu anda bir döngüyle olay ataması ile uğraşıyorum.

    PHP:
    for(var i in kategoriler)
    {  var 
    tus document.createElement("button");
       
    tus.addEventListener("click", function(){ alert(kategoriler[i]["AD"]) }, false);
       
    document.getElementById("cerceve").appenChild(tus);
    }
    Bu atama şekliyle her bir tuşta da verilen alert aynı değere sahip olur. Oysa biz her bir tuşa bastığımızda atadığımız değerin alert olmasını istiyoruz. Atanan değerler ise her bir kategorimizin adı.

    Bu 20-30 dk düşünmemi sağlayan bir sorun oldu. Ama farkettim ki ben Javascript'in neyi ne zaman nasıl atama yaparak çalıştırdığını doğru öğrenmemişim veya anlayamamışım.

    Bu eksik bilgimi daha basit bir örnekle kolayca anladım.
    PHP:
    var k=15;
    var 
    = function(){ alert(k); }
    k10;
    a();
    Bu kod benim yaşadığım sorun için birebir örnek özelliği taşıyor. Sonuç itibariyle ekranda 1 alert belirir ve ekrana 10 yazar. Oysa ben k=15 olduğu sırada değişkenime atama yapıyorum. Fakat değişkene yapılan atama bir kapsama yöntemiyle yapılıyor. Ve bu atama değişkenlerin değerlerini umursamadan direk kodu atıyor. a() çalıştırdığınız sırada, içersindeki tüm kodlar ve değişkenlerde dahil olmak üzere çalışıyor.

    Bu noktada sizin gösterdiğiniz yöntem sorunu çözer nitelikte. Yani bu örnekte de doğru olan atama sizinde gösterdiğiniz gibi şu şekilde olmalı.
    PHP:
    var k=15;
    var 
    = function()
    {   var 
    x=k;
         return function()
        { 
    alert(k);}
    }();

    k10;
    a();
    Artık ekranda 15 değerli alert görünür...

    Tekrar yardımlarınız için teşekkürler...