If you're seeing this message, it means we're having trouble loading external resources on our website.

Bağlandığınız bilgisayar bir web filtresi kullanıyorsa, *.kastatic.org ve *.kasandbox.org adreslerinin engellerini kaldırmayı unutmayın.

Ana içerik

Buton nesne türü

Kodu tekrardan kullanılabilir ve kuvvetli yapmanın en iyi yollarından biri, özellikle buton gibi UI kontrolleri yapmak için, nesne tabanlı programlama kullanmaktır. Nesne-tabanlı programlamada, program dünyamızı belirli davranışı olan soyut nesne türleri cinsinden düşünürüz ve daha sonra belirli parametrelerle bu nesne türlerinin örneklerini oluştururuz. Bunu JavaScript'de nasıl yapacağınızı hatırlamıyorsanız, burada tekrar gözden geçirin.
Butonları oluşturmada OOP'yi kullanmak için, bir Buton nesne türü tanımlamamız ve sonra da üzerinde, çizmek ve fareyle tıklamaları işlemek gibi yöntemler tanımlamamız gerekir. Şöyle görünen bir kod yazabilmek isteriz:
var btn1 = new Button(...);
btn1.draw();

mouseClicked = function() {
  if (btn1.isMouseInside()) {
     println("Whoah, you clicked me!");
  }
}
Bunu bir önceki makalede yazdığımız kodla karşılaştıralım:
var btn1 = {...};
drawButton(btn1);

mouseClicked = function() {
  if (isMouseInside(btn1)) {
     println("Whoah, you clicked me!");
  }
}
Bunlar çok benzer, öyle değil mi? Ama burada çok büyük bir fark var -- fonksiyonların hepsi, Buton nesne türünün üzerinde tanımlanmıştır, aslında düğmelere aittirler. Özellikler ve davranış arasında daha sıkı bir bağlantı sağlanabilir ve bu daha temiz ve kullanılabilir bir koda yol açar.
Buton nesne türünü tanımlamak için, oluşturucuyla başlamamız gerekir: konfigürasyon parametrelerini alan ve nesne oluşumunun başlangıçtaki özelliklerini ayarlayan özel fonksiyon.
İlk deneme olarak, burada x, y, en, ve yüksekliği alan bir oluşturucuyu bulabilirsiniz:
var Button = function(x, y, width, height) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
};

var btn1 = new Button(100, 100, 150, 150);
Bu kesinlikle işe yarar, ama önermek istediğim başka bir yaklaşım var. Parametreleri teker teker almak yerine, oluşturucu bir konfigürasyon nesnesini de alabilir.
var Button = function(config) {
    this.x = config.x;
    this.y = config.y;
    this.width = config.width;
    this.height = config.height;
    this.label = config.label;
};
Konfig nesnesinin avantajı, oluşturucunun işlemesi için parametre eklemeye devam edebilmemiz (label gibi), ve, yine de, butonu oluşturduğumuzda, her parametrenin ne yaptığını kolaylıkla anlayabilmemizdir:
var btn1 = new Button({
    x: 100, y: 100,
    width: 150, height: 50,
    label: "Please click!"});
Ama bir adım öteye gidebiliriz. Ya butonların çoğu aynı en veya yükseklikteyse? Her buton için en ve yükseklik parametrelerini belirtmemize gerek olmamalıdır, bunları sadece gerektiğinde belirtmeliyiz. Oluşturucunun özelliğin konfig nesnesinde tanımlı olup olmadığını kontrol etmesini, ve tanımlı değilse, ön tanımlı bir değer ayarlamasını isteyebiliriz. Aşağıdaki gibi:
var Button = function(config) {
    this.x = config.x || 0;
    this.y = config.y || 0;
    this.width = config.width || 150;
    this.height = config.height || 50;
    this.label = config.label || "Click";
};
Şimdi bunu özelliklerin bir alt kümesiyle çağırabiliriz, çünkü diğerleri ön tanımlı değere ayarlanmış olacaktır:
var btn1 = new Button({x: 100, y: 100, label: "Please click!"});
Bir oluşturucu için bu kadar çaba harcıyoruz, öyle mi? Ancak, gerçekten değecek, size söz veriyorum.
Artık oluşturucuyu hallettiğimize (iliklediğimize?) göre, biraz davranış tanımlayalım: draw yöntemi. Kodu drawButton fonksiyonuyla aynı olacak, ama özelliklerin hepsini bundan alacak, çünkü nesne prototipine göre tanımlanmıştır:
Button.prototype.draw = function() {
    fill(0, 234, 255);
    rect(this.x, this.y, this.width, this.height, 5);
    fill(0, 0, 0);
    textSize(19);
    textAlign(LEFT, TOP);
    text(this.label, this.x+10, this.y+this.height/4);
};
Bu tanımlandıktan sonra, şöyle çağırabiliriz:
btn1.draw();
Burada, Button nesnesini kullanarak 2 buton oluşturan bir program bulabilirsiniz - birden çok buton oluşturmak ve çizmenin ne kadar kolay olduğuna dikkat edin:
Ancak, zor kısmı atladık, tıklamaları işleme. Button prototipi üzerinde, kullanıcı belirli bir butonun içine tıkladığında doğru sonucunu verecek bir fonksiyon tanımlamakla başlayabiliriz. Bu, yine önceki fonksiyonumuzla aynıdır; ama geçirilen bir nesne yerine, tüm özellikleri thisten alır:
Button.prototype.isMouseInside = function() {
    return mouseX > this.x &&
           mouseX < (this.x + this.width) &&
           mouseY > this.y &&
           mouseY < (this.y + this.height);
};
Artık bunu bir mouseClicked fonksiyonunun içinden kullanabiliriz:
mouseClicked = function() {
    if (btn1.isMouseInside()) {
        println("You made the right choice!");
    } else if (btn2.isMouseInside()) {
        println("Yay, you picked me!");
    }
};
Butonların her birini tıklayarak, bunu aşağıda deneyin:
Ancak, burada bütün bu tıklamaların işlenmesine yaptığımız ayar ile ilgili benim canımı sıkan bir şey var. Nesne tabanlı programlamanın tüm amacı, bir nesnenin içindeki başka bir nesnenin davranışlarını birleştirmek, ve davranışı özelleştirmek için özellikler kullanmaktır. Ancak, davranışların bazılarını nesnenin dışında bıraktık, mouseClicked'in içinde println:
mouseClicked = function() {
    if (btn1.isMouseInside()) {
        println("You made the right choice!");
    } else if (btn2.isMouseInside()) {
        println("Yay, you picked me!");
    }
};
Bu print ifadeleri her butona bir şekilde bağlansa iyi olur, oluşturucuya geçen bir şey gibi. Şimdi buna baktığımızda, oluşturucu konfig'e bir mesaj iletmeyi ve bunun çıktısı için bir handleMouseClick fonksiyonu tanımlamayı düşünebiliriz:
var Button = function(config) {
    ...
    this.message = config.message || "Clicked!";
};

Button.prototype.handleMouseClick = function() {
    if (this.isMouseInside()) {
         println(this.message);
    }
};

var btn1 = new Button({
    x: 100,
    y: 100,
    label: "Please click!",
    message: "You made the right choice!"
});

mouseClicked = function() {
   btn1.handleMouseClick();
};
Bu çok daha güzel olur, çünkü artık her butonun belirli davranışıyla ilgili her şey, oluşturucunun içinde paketlidir. Ama, fazla basittir. Ya mesaj çıktısının yanı sıra bir şey yapmak isteseydim, birkaç şekil çizmek veya sahneyi değiştirmek gibi birkaç satır gerektiren bir şey? Bu durumda, oluşturucuya bir dizeden fazlasını vermemiz gerekirdi -- ona bir grup kod sağlamak isterdik. Bir grup kodu nasıl çevirebiliriz?
...Bir fonksiyonla! (Her dilde olmasa da) JavaScript'de, fonksiyonları fonksiyonların parametreleri olarak iletebiliriz. Bu birçok durumda faydalıdır, ama özellikle, buton gibi UI kontrolleri için davranış tanımlarken faydalıdır. Butona, "hey, burada şu fonksiyon var, kullanıcı butona tıkladığında çağırmanı istediğim bir grup kod" diyebiliriz. Bu fonksiyonlara "callback" fonksiyonları deriz, çünkü bunlar hemen çağrılmaz, bir süre sonra, uygun bir zamanda "geri çağrılırlar".
Fonksiyon olan bir onClick parametresi iletmekle başlayabiliriz:
var btn1 = new Button({
    x: 100,
    y: 100,
    label: "Please click!",
    onClick: function() {
       text("You made the right choice!", 100, 300);
    }
});
Sonra, neyin iletildiğine göre, oluşturucumuzun bir onClick özelliği ayarladığından emin olmalıyız. Ön tanımlı değer için, onClick iletilmediği durumda, bir "no-op" fonksiyonu oluşturacağız -- bu, "hiç işlem yapmayan" bir fonksiyondur. Sadece onu çağırmamız ve bir hata almamamız için oradadır:
var Button = function(config) {
    // ...
    this.onClick = config.onClick || function() {};
};
Son olarak, kullanıcı butona tıkladıktan sonra, callback fonksiyonunu geri çağırmamız gerekir. Bu, aslında, son derece basittir- onu kaydettiğimiz özellik ismini yazarak ve bunu boş parantezle izleyerek çağırabiliriz:
Button.prototype.handleMouseClick = function() {
    if (this.isMouseInside()) {
        this.onClick();
    }
};
Artık bitirdiğimize göre - kolaylıkla yeni buton oluşturabileceğimiz, her butonun farklı görünmesini ve tıklama olaylarına farklı tepki vermesini sağlayabileceğimiz bir Buton nesnemiz var. Aşağıdaki örnekte etrafa tıklayın, ve buton parametrelerini değiştirdiğinizde neler olduğunu görün:
Artık bunu bir şablon olarak oluşturduğunuza göre, butonlarınızı başka şekillerde de özelleştirebilirsiniz, örneğin farklı renklerde yapabilirsiniz, veya mouseover gibi başka olaylara tepki vermelerini sağlayabilirsiniz. Bunu programlarınızda deneyin!

Tartışmaya katılmak ister misiniz?

Henüz gönderi yok.
İngilizce biliyor musunuz? Khan Academy'nin İngilizce sitesinde neler olduğunu görmek için buraya tıklayın.