Nejen Béda Trávníček, ale i návštěvníci vašich stránek mohou radostně volat „a mám to zadarmo!“ – pokud jim dáte k dispozici následující javascriptovou ruletu, která se po určitých úpravách docela dobře využít třeba v internetovém obchodě pro generování slev.

Podívejme se nyní, jak to funguje. Stiskněte tlačítko „Spustit ruletu“ a chvíli počkejte – po doběhnutí animace se výsledek zobrazí v alert okénku:

Poznámka: pokud nyní stisknete "Spustit ruletu" podruhé, dostanete stejný výsledek - aby se ruleta zastavila na jiném čísle, musíte nejprve obnovit (reload) tuto stránku. Důvody k takové funkčnosti jsou vysvětleny v závěru článku.

Kód, zabezpečující činnost rulety, je následující. Nejprve vytvoříme pomocné pole fields, které ve svých prvcích obsahuje hodnoty (např. procentní hodnoty slevy) pro jednotlivá pole rulety. Pole vytváříme oblíbeným konstruktorem CreateArray, který přijímá libovolný počet argumentů. Můžeme tedy vytvořit ruletu delší či kratší, zcela podle našich potřeb:

var fields = new CreateArray(10, 20, 5, 8,15, 45, 80, 100, 5, 0, 31, 1, 12, 4 );
function CreateArray(){
    this.length = CreateArray.arguments.length
    for (var i = 0; i < this.length; i++)
    this[i + 1] = CreateArray.arguments[i]
}

Kromě uvedeného pole rovněž zadefinujeme všechny potřebné pomocné proměnné - jejich význam si vysvětlíme níže jednotlivě:

var destIndex
var startIndex = 1
var timeout = 50
var iterations = 0

Následuje nejdelší funkce createPlayfield() - ta vygeneruje pomocí document.write formulář a tabulku se všemi políčky pro ruletu, hodnotami jednotlivých polí a tlačítkem "Spustit ruletu":

function createPlayfield() {
    document.write("<form name=\"automat\"><div align=\"center\">")
    document.write("<table bgcolor=\"#00FF00\">")
    document.write("<tr><td align=\"center\" colspan=\"" + fields.length +"\">")
    document.write("<strong>A mám to zadarmo!</strong></td></tr><tr>")
    for(i=1; i<=fields.length; i++ ) {
        document.write("<td align=\"center\">" + fields[i] + "</td>")
    }
    document.write("</tr><tr>")
    for(i=1; i<=fields.length; i++ ) {
        document.write("<td align=\"center\"><input type=\"radio\" value=\"" + i + "\"name=\"points\"></td>")
    }
    document.write("</tr><tr>")
    document.write("<td align=\"center\" colspan=\"" + fields.length + "\">")
    document.write("<input type=\"button\" value=\"Spustit ruletu\" name=\"run\" onclick=\"runRoulette()\"></td>")
    document.write("</tr></table></div></form>")
    destIndex = randNum( fields.length )
}

Samotná funkce je pouze množství volání document.write, a tedy celkem nezajímavá, podívejme se v několika poznámkách spíše na HTML kód, který generuje:

  • Formulář je pojmenován "automat" kvůli snadné adresaci.
  • Jednotlivá formulářová pole - radiobuttony - jsou pojmenovány "points" a jejich hodnoty jsou nastaven na 1..n , kde n je počet prvků pole fields.
  • Tlačítko "run" spustí ruletu tak, že při události onclick zavolá funkci runRoulette().

Na posledním řádku uvedené funkce je jedna zajímavost: pomocí volání funkce randNum()...

function randNum (num) {
var rnd1 = Math.round( (num-1) * Math.random() + 1 )
    return rnd1;
}

..zde inicializujeme proměnnou destIndex na náhodnou hodnotu v rozsahu 1..n, kde n je počet prvků pole fields. Tato proměnná určuje index pole, na kterém se kulička rulety zastaví. Znamená to tedy, že výsledek rulety je určen předem. Má to svůj význam, který si ukážeme později.

Zbývá nám poslední část obsluhy rulety - funkce runRoulette(), která provádí veškerou animaci rulety, zastavení na určeném prvku a zobrazení závěrečného hlášení:

function runRoulette() {
var myfield = eval("document.automat.points["+(startIndex-1)+"]")
myfield.checked = false
startIndex++
if( startIndex > fields.length ) {
startIndex = 1
}
myfield = eval("document.automat.points["+(startIndex-1)+"]")
myfield.checked = true
iterations++
if ((iterations>50) && (iterations<100) ) {
    timeout +=10
}
if ( ( iterations<100) || (startIndex != destIndex) ) {
    window.setTimeout('runRoulette()',timeout);
} else {
    alert ("Vyhral jste slevu ve vysi " + fields[startIndex] + "%!" );
}   
}

V první části této funkce provedeme animaci - odstraníme "kuličku" v aktivním poli rulety, toto aktivní pole (máme jej poznačené v proměnné startIndex) posuneme o jedno doprava a na nové pozici opět "kuličku" zobrazíme.

Prostřední část funkce zabezpečuje postupné zpomalování běhu kuličky. Počet kroků, který již proběhl, máme uložen v proměnné iterations, aktuální nastavení časovače (tedy interval v milisekundách) je poznačen v proměnné timeout. Tuto animaci zpomalování lze libovolně upravovat - požadujeme-li delší, popř. kratší běh rulety.

Závěrečná část funkce obsahuje jednak opětovné volání funkce runRoulette() pomocí časovače, a dále ukončení běhu rulety. Po dosažení určeného počtu iterací (v našem případě 100), ještě počkáme, až bude kulička na předem určené pozici, a poté zastavíme běh funkce a vyhlásíme "překvapující" výsledek.

Ještě jeden řádek JavaScriptu musíme napsat - jedná se o volání funkce createPlayfield(), které provedeme na tom místě stránky, kde má být ruleta umístěna:

createPlayfield()

Ruleta a bezpečnost

Uvedenou ruletu lze - za jistých úprav - použít i pro reálné generování slev například v internetovém obchodě. Pochopitelně, JavaScript není bezpečný - nemůžeme tedy postupovat tak, že bychom spustili ruletu, nechali náhodně vygenerovat slevu, a poté provedli redirekci třeba na ASP stránku, která by odečetla slevu od ceny objednávky - takovou techniku by bylo pro zdatnější návštěvníky snadné napadnout.

Lze však postupovat obráceně. Slevu vygenerujeme v relativně bezpečné serverové části - ASP, PHP, uložíme ji (do databáze, objektu session atd.) a teprve poté zavoláme stránku s ruletou - ta však už má jen ten účel, že provede zajímavou animaci - o hodnotě slevy je již předem rozhodnuto a návštěvník ji nemůže nijak ovlivnit. JavaScript, uvedený v tomto článku, je na takovou možnost už přichystán - stačí náhodné generování hodnoty proměnné destIndex nahradit její inicializací na pevnou hodnotu v rámci definice proměnné (což může provést serverový skript). Rovněž předpokládám spuštění rulety přímo po načtení stránky - například využitím události onload. Proto také není tlačítko "Spustit ruletu" ošetřeno proti dvojímu stisknutí - v reálné aplikaci bychom jej pravděpodobně nepoužili.

Přeji vám příjemný den.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Žádný příspěvek v diskuzi

Odpovědět