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

Ha webszűrőt használsz, győződj meg róla, hogy a *.kastatic.org és a *.kasandbox.org nincsenek blokkolva.

Fő tartalom

Gomb függvény

Ha végigcsináltad a Bevezetés a JS-be kurzust, akkor már készítettél gombokat az Az első gombod és az Okosgomb logikai feladatokban. Ha esetleg elfelejtetted, ismételjük át, hogyan kell elkészíteni egy egyszerű gombot:
Először is, mire van minimum szükségünk egy gombhoz?
  1. Egy alakzatra a vásznon (tipikusan egy téglalapra)
  2. Egy címkére vagy ikonra, ami leírja mit csinál a gomb
  3. Arra, hogy reagáljon, ha a felhasználó rákattint (ha máshova kattint, akkor ne történjen semmi)
Az 1-es és 2-es pontot könnyen meg tudjuk csinálni:
fill(0, 234, 255);
rect(100, 100, 150, 50, 5);
fill(0, 0, 0);
textSize(19);
text("Useless button", 110, 133);
A 3-as teljesítéséhez definiálnunk kell egy mouseClicked függvényt, melyet meghívunk minden alkalommal, amikor a felhasználó kattint a gomb területén, ehhez pedig meg kell vizsgálunk azt, hogy a mouseX és a mouseY a gomb befoglaló téglalapján belül helyezkedik-e el. A lenti gomb esetén például az x 100 és 250 között van, az y pedig 100 és 150 között, ahogy ezt az ábrán láthatod is:
A koordinátákat vizsgálhatjuk összevont feltételekkel, &&-eket használva:
mouseClicked = function() {
    if (mouseX >= 100 && mouseX <= 250 &&
        mouseY >= 100 && mouseY <= 150) {
        println("Still pretty useless");    
    }
};
Próbálj meg rákattintani, majd mellé is kattintani, hogy meggyőződj róla, valóban működik-e:
Az látszik, hogy működik, viszont valami egy kicsit aggaszt engem... Attól tartok, hogy nem igazán használható újra ez a kód. Mennyit kell majd kódolnom, ha szeretném máshova helyezni a gombot? (Próbáld csak ki fentebb!) Sok „beégetett” értéket látok a kódban – például a koordinátákat a mouseClicked függvényben –, ezért el is kezdtem azon gondolkodni, hogy nem lehetne-e ezt tisztábban, olvashatóbban megcsinálni.
Kezdjük azzal, hogy a helyzetet és a méretet változókban tároljuk, így elég lesz majd egyetlen helyen megváltoztatni, és a gomb továbbra is működni fog. Hozzáadtam a btnX, btnY, btnWidth és btnHeight változókat az alábbi programhoz. Próbáld ki, hogy megváltoztatod az értéküket, és aztán rákattintasz a gombra:
Ez most már jobb. De még mindig jó kérdés, mennyit kellene kódolnom, ha egy másik gombot is szeretnék használni. Le kell másolhatom a kódot, és készítenem kell egy btn2X és btn2Y változót? Ez nem hangzik túl szórakoztatónak. Szívesebben írnék inkább egy függvényt, ami mindent tartalmaz, ami a gombokban hasonló, és paramétereket használnék arra, ami különbözik. Ezt megírhatjuk például így, paraméterekké alakítva a változóinkat:
var drawButton = function(btnX, btnY, btnWidth, btnHeight) {
    fill(0, 234, 255);
    rect(btnX, btnY, btnWidth, btnHeight, 5);
    fill(0, 0, 0);
    textSize(19);
    textAlign(LEFT, TOP);
    text("Useless button", btnX+10, btnY+btnHeight/4);
};
És így hívhatjuk meg:
drawButton(100, 100, 150, 50);
De, jajj... mi lesz így a mouseClicked kódunkkal? Látod, mi lenne vele a gond?
mouseClicked = function() {
    if (mouseX >= btnX && mouseX <= (btnX+btnWidth) &&
        mouseY >= btnY && mouseY <= (btnY+btnHeight)) {
        println("Still pretty useless");    
    }
};
Ha ezeket a kódokat együtt használjuk, hibaüzenetet kapunk a 'Jaj ne' figurától, miszerint „btnX nem definiált” – és igaza is van! A btnX-et függvény paraméterként használjuk, vagyis ez többé már nem globális változó. Ez így remek újra-felhasználhatóság szempontjából a drawButton függvényben, de a mouseClicked függvény most nem tudja, melyik koordinátákat kellene vizsgálnia.
Ki kell találnunk valamit, hogy átadhassuk az információt a drawButton-nak, és ezt az információt elérhetővé tegyük a mouseClicked-nek is. Van is rá pár ötletem:
  1. Vezessünk be ismét globális változókat a pozíciónak és a méreteknek (btnX, btnY, btnWidth, btnHeight)
  2. Hozzunk létre egy globális tömböt, ami minden paramétert tárol (var btn1 = [...];)
  3. Hozzunk létre egy globális objektumot, ami minden paramétert tárol (var btn1 = {..})
  4. Használjunk objektum-orientált elveket a gombok és tulajdonságaik tárolásához (var btn1 = new Button(...))
Melyiket válasszuk? Nekem nem tetszik az első megoldás, mert nagyon sok globális változót kellene használnunk, és allergiás vagyok a globális változókra. A második sem tetszik, mert nehéz olyan kódot olvasni, ahol az adat kiválasztása tömbindexeken múlik. A harmadik módszer viszont tetszik, mert csak egy globális változót vezet be, és olvashatóbb kódot eredményez. A negyedik módszer is tetszik, mert az objektum-orientált elvekkel egy általános Button (gomb) objektumtípust hoz létre, de ezt a megoldást hagyjuk későbbre.
Hozzuk létre a globális btn1 változónkat:
var btn1 = {
    x: 100,
    y: 100,
    width: 150,
    height: 50
};
És változtassuk meg a drawButton függvényünket, hogy egyetlen objektumot fogadjon el, és ennek a tulajdonságait használja fel:
var drawButton = function(btn) {
    fill(0, 234, 255);
    rect(btn.x, btn.y, btn.width, btn.height, 5);
    fill(0, 0, 0);
    textSize(19);
    textAlign(LEFT, TOP);
    text("Useless button", btn.x+10, btn.y+btn.height/4);
};
A mouseClicked függvény megvizsgálja a globális változó tulajdonságait:
mouseClicked = function() {
    if (mouseX >= btn1.x && mouseX <= (btn1.x+btn1.width) &&
        mouseY >= btn1.y && mouseY <= (btn1.y+btn1.height))     {
        println("Still pretty useless");    
    }
};
Próbáld ki az alábbit! Mint korábban, változtasd meg a gomb paramétereit, és nézd meg, hogy továbbra is működik-e:
Ennek az egésznek az volt a célja, hogy könnyen tudjunk majd új gombokat hozzáadni – nem más tehát, mint az újrafelhasználhatóság! Működik vajon? Lássuk!
Egy új globális változóval kezdjük, btn2, és toljuk el egy kicsit az első gombhoz képest az y tengely mentén:
var btn2 = {
    x: 100,
    y: 200,
    width: 150,
    height: 50
};
Rajzoljuk meg ezt a gombot is:
drawButton(btn2);
Ezzel megrajzoltunk két gombot a vászonra, de csak az első reagál a kattintásokra. Elérhetjük, hogy a második is reagáljon, ehhez duplikáljuk a logikát, és kicseréljük a btn2-t btn1-re:
mouseClicked = function() {
    if (mouseX >= btn1.x && mouseX <= (btn1.x+btn1.width) &&
        mouseY >= btn1.y && mouseY <= (btn1.y+btn1.height))     {
        println("Still pretty useless");    
    }

    if (mouseX >= btn2.x && mouseX <= (btn2.x+btn2.width) &&
        mouseY >= btn2.y && mouseY <= (btn2.y+btn2.height))     {
        println("2nd one still quite useless!");    
    }
};
Téged nem idegesít ez a sok ismételt kód? Készítsünk egy isMouseInside függvényt, ami tudni fogja, hogyan ellenőrizzen egy gomb objektumot, és térjen vissza igaz értékkel, ha az egerünk a gomb területén van:
var isMouseInside = function(btn) {
    return (mouseX >= btn.x &&
            mouseX <= (btn.x+btn.width) &&
            mouseY >= btn.y && 
            mouseY <= (btn.y+btn.height));
};
És most használjuk ezt a függvényt a mouseClicked függvényben belül, nagyban lecsökkentve az ismétlődő kódmennyiséget:
mouseClicked = function() {
    if (isMouseInside(btn1))     {
        println("Still pretty useless");    
    } else if (isMouseInside(btn2))     {
        println("2nd one still quite useless!");    
    }
};
És készen is van! Függvények használatával több gombot is kirajzoltunk, és most már aránylag könnyű új gombokat hozzáadni. Próbáld is ki az alábbi kódot:
Folytathatnánk akár – tömböket hozhatnánk létre a program gombjainak tárolásához, testre szabhatnánk a címkéket és a gombok színét –, de ennyi egyelőre valószínűleg elég alapot adott ahhoz, hogy függvények segítségével egyszerű gombokat tudj létrehozni. A következőkben meg fogjuk nézni, hogyan készíthetsz gombokat objektum-orientált alapelveket használva.

Szeretnél részt venni a beszélgetésben?

Még nincs hozzászólás.
Tudsz angolul? Kattints ide, ha meg szeretnéd nézni, milyen beszélgetések folynak a Khan Academy angol nyelvű oldalán.