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

Pokud používáš webový filtr, ujisti se, že domény: *.kastatic.org and *.kasandbox.org jsou vyloučeny z filtrování.

Hlavní obsah

Funkce tlačítka

Pokud máš za sebou Úvod do kurzu JS, pak již umíš vytvořit několik jednoduchých tlačítek z logických výzev Tvoje první tlačítko a Chytré tlačítko. V případě, že si to už nepamatuješ, pojďme si znovu projít, jak vytvořit jednoduché tlačítko.
Zaprvé, jaké jsou nejzákladnější vlastnosti tlačítka?
  1. Tvar na plátně (obvykle obdélník)
  2. Obsahuje nápis nebo ikonu popisující, co udělá
  3. Reaguje na kliknutí uživatele (ale ne mimo tlačítko)
Vlastností #1 a #2 můžeme dosáhnout docela snadno:
fill(0, 234, 255);
rect(100, 100, 150, 50, 5);
fill(0, 0, 0);
textSize(19);
text("Nepoužitelné tlačítko", 110, 133);
Abychom dosáhli vlastnosti #3, musíme definovat funkci mouseClicked, která bude volána při kliknutí uživatelem, a uvnitř této funkce musíme zkontrolovat, zda jsou mouseX a mouseY uvnitř ohraničujícího rámečku tlačítka. Pro výše uvedené tlačítko je ohraničení od x=100 do x=250 a od y=100 do y=150, jak je znázorněno na následujícím obrázku:
Tyto souřadnice můžeme zkontrolovat za použití && pro všechny čtyři podmínky:
mouseClicked = function() {
    if (mouseX >= 100 && mouseX <= 250 &&
        mouseY >= 100 && mouseY <= 150) {
        println("Pořád celkem nepoužitelné");    
    }
};
Zkus kliknout na tlačítko i mimo něj, ověříš tak, zda to funguje:
Funguje to, ale něco se mi pořád nezdá. Obávám se, že náš kód není příliš opakovatelně použitelným kódem. Představ si, kolik práce budu potřeba vynaložit, pokud chci změnit polohu tlačítka? (Vyzkoušej si to nahoře!) V kódu vidím spoustu "tvrdě kódovaných" čísel -- jako jsou souřadnice ve funkci mouseClicked, a hned mě napadá, jestli neexistuje efektivnější způsob.
Začneme tím, že si vytvoříme proměnné pro polohu a velikost, abychom je mohli změnit na jednom místě a abychom zachovali kliknutí na tlačítko pořád funkční. Do níže uvedeného programu jsme přidali btnX, btnY, btnWidth a btnHeight. Zkus změnit jejich hodnoty a klikni na tlačítko:
Hned je to lepší. Kolik práce by nám teď přidání dalšího tlačítka dalo? Musíme vše zkopírovat a vložit a vytvořit btn2X, btn2Y? No, to nezní moc zábavně. Je to pro nás dobrou motivací pro to, abychom napsali funkci, která se o všechno související s tvorbou tlačítka postará. Pro ostatní věci použijeme parametry. Mohli bychom to napsat následovně, změnou proměnných na parametry:
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("Nepoužitelné tlačítko", btnX+10, btnY+btnHeight/4);
};
Pak kód zavoláme následujícím způsobem:
drawButton(100, 100, 150, 50);
Ale ne, zapomněli jsme na náš kód pro mouseClicked. Vidíš, jaký problém by s ním mohl být?
mouseClicked = function() {
    if (mouseX >= btnX && mouseX <= (btnX+btnWidth) &&
        mouseY >= btnY && mouseY <= (btnY+btnHeight)) {
        println("Pořád celkem nepoužitelné");    
    }
};
Kdybychom použili všechen kód dohromady, dostali bychom chybové hlášení od Oh Noes, že "btnX není definovaný" - a je to pravda! Změnili jsme btnX na funkční parametr, což znamená, že už není globální proměnnou. To je skvělé pro opětovnou použitelnost funkce drawButton, ale nyní funkce mouseClicked nemá žádný způsob, jak zjistit, které souřadnice mají být kontrolovány.
Potřebujeme tedy přijít na hezký způsob, jak předat informace do drawButton a zpřístupnit tyto informace pro mouseClicked. Napadá nás několik možností:
  1. Znovu zavést globální proměnné pro polohu a velikost (btnX, btnY, btnWidth, btnHeight)
  2. Zavést globální pole, které ukládá všechny parametry (var btn1 = [...];)
  3. Zavést globální objekt, který ukládá parametry (var btn1 = {..})
  4. Použít objektově orientované principy k definování tlačítka a uložení vlastností (var btn1 = new Button(...))
Kterou možnost si vybrat? No, první se mi nelíbí, protože budeme muset přidat hodně globálních proměnných a na globální proměnné mám alergii. Nemám rád ani druhou techniku, protože je těžké přečíst kód, který bere data na základě ukazatelů pole. Líbí se mi třetí technika, protože zavádí pouze jednu globální proměnnou a vytvoří čitelnější kód. Také se mi líbí čtvrtá technika, která používá objektově orientované principy k vytvoření generických objektových typů Button, ale nechme si ji na později.
Náš globální objekt btn1 můžeme vytvořit následovně:
var btn1 = {
    x: 100,
    y: 100,
    width: 150,
    height: 50
};
A změníme funkci drawButton tak, aby akceptovala jeden objekt, ze kterého pak převezme vlastnosti:
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("Nepoužitelné tlačítko", btn.x+10, btn.y+btn.height/4);
};
Funkce mouseClicked zkontroluje vlastnosti globální proměnné:
mouseClicked = function() {
    if (mouseX >= btn1.x && mouseX <= (btn1.x+btn1.width) &&
        mouseY >= btn1.y && mouseY <= (btn1.y+btn1.height))     {
        println("Pořád celkem nepoužitelné");    
    }
};
Vyzkoušej si to níže! Zkus změnit různé parametry tlačítka a uvidíš, jestli vše stále funguje:
Princip spočívá v tom, že chceme být schopni snadno přidat další tlačítka, jedná se o finální test opakovatelnosti. Můžeme to udělat? Ba Bum BUM.
Začneme novou globální proměnnou btn2, posunutou směrem y od prvního tlačítka:
var btn2 = {
    x: 100,
    y: 200,
    width: 150,
    height: 50
};
Pak nakreslíme toto tlačítko:
drawButton(btn2);
Tím se nám podaří na plátně nakreslit 2 tlačítka, ale pouze první bude reagovat na kliknutí. Druhé uděláme responzivním tak, že duplikujeme logiku a vyměníme btn2 za btn1, jak je to následovně:
mouseClicked = function() {
    if (mouseX >= btn1.x && mouseX <= (btn1.x+btn1.width) &&
        mouseY >= btn1.y && mouseY <= (btn1.y+btn1.height))     {
        println("Pořád celkem nepoužitelné");    
    }

    if (mouseX >= btn2.x && mouseX <= (btn2.x+btn2.width) &&
        mouseY >= btn2.y && mouseY <= (btn2.y+btn2.height))     {
        println("Druhé je taky celkem nepoužitelné!");    
    }
};
Ale není ti z toho všeho znovu použitelného kódu tak trochu špatně? Vytvořme funkci isMouseInside, která ví, jak zkontrolovat jakýkoli objekt tlačítka a vrátit true, pokud se myš nacházela uvnitř něj:
var isMouseInside = function(btn) {
    return (mouseX >= btn.x &&
            mouseX <= (btn.x+btn.width) &&
            mouseY >= btn.y && 
            mouseY <= (btn.y+btn.height));
};
A nyní můžeme použít tuto funkci uvnitř mouseClicked pro výrazné snížení znovu opakovaného kódu:
mouseClicked = function() {
    if (isMouseInside(btn1))     {
        println("Pořád celkem nepoužitelné");    
    } else if (isMouseInside(btn2))     {
        println("Druhé je taky celkem nepoužitelné!");    
    }
};
A máme to! Použili jsme funkce k nakreslení několika tlačítek a poměrně snadno přidáváme nová tlačítka. Vyzkoušej to níže:
Mohli bychom pokračovat – vytvářet pole všech tlačítek v programu, umožňujíc přizpůsobení popisku a barvy tlačítka - ale toto ti snad poskytlo dobrý základ pro vytváření jednoduchých tlačítek pomocí funkcí. Příště si projdeme to, jak vytvořit jednoduchá tlačítka pomocí objektově orientovaných principů.

Chceš se zapojit do diskuze?

Zatím žádné příspěvky.
Umíš anglicky? Kliknutím zobrazíš diskuzi anglické verze Khan Academy.