Přidání budíků do digitálních hodin

Minulý týden jsme vytvořili digitální hodiny poháněné jQuery &CSS3. V této aktualizaci přidáme podporu pro nastavení budíků pomocí zvukového prvku HTML5.

Nápad

Abychom rozšířili digitální hodiny o podporu budíků, musíme do kódu z minulého týdne přidat několik zásadních funkcí:

  • Potřebujeme lidem umožnit nastavit a upravit budíky. To by vyžadovalo nějaký druh dialogu s poli pro nastavení času budíku;
  • Každou sekundu budeme muset zkontrolovat, zda se má spustit alarm. Pokud by mělo, přehrajeme malý zvukový soubor a zobrazíme dialog „Čas vypršel“.

Tyto funkce budou vyžadovat změny v HTML, CSS a jQuery. Začněme!

HTML

Budeme mít dva dialogy – jeden pro nastavení/úpravu budíku a druhý, který se zobrazí, když se spustí budík.

index.html

<div class="overlay">

    <div id="alarm-dialog">

        <h2>Set alarm after</h2>

        <label class="hours">
            Hours
            <input type="number" value="0" min="0" />
        </label>

        <label class="minutes">
            Minutes
            <input type="number" value="0" min="0" />
        </label>

        <label class="seconds">
            Seconds
            <input type="number" value="0" min="0" />
        </label>

        <div class="button-holder">
            <a id="alarm-set" class="button blue">Set</a>
            <a id="alarm-clear" class="button red">Clear</a>
        </div>

        <a class="close"></a>

    </div>

</div>

<div class="overlay">

    <div id="time-is-up">

        <h2>Time's up!</h2>

        <div class="button-holder">
            <a class="button blue">Close</a>
        </div>

    </div>

</div>

Obě tato dialogová okna jsou pomocí CSS skryta a v případě potřeby se zobrazují pomocí metody jQuery fadeIn(). Další věc, která stojí za zmínku, je, že dialogové okno budíku používá číslo HTML5 typy vstupů s min hodnotu 0. Číselné vstupy lze velmi snadno ověřit pomocí JavaScriptu (o tom více v další části) a také zobrazí číselnou klávesnici na mobilních zařízeních.

Další je zvukový prvek HTML5. Obsahuje zdrojové značky se dvěma různými formáty zvuku. První je mp3 verze zvuku budíku a druhá ogg. Formát ogg je potřeba pouze ve Firefoxu, který zatím nepodporuje přehrávání mp3 kvůli problémům s licencí. Téměř všechny ostatní prohlížeče, které podporují zvuk HTML5, podporují také mp3.

index.html

<audio id="alarm-ring" preload>
    <source src="assets/audio/ticktac.mp3" type="audio/mpeg" />
    <source src="assets/audio/ticktac.ogg" type="audio/ogg" />
</audio>

Atribut preload říká prohlížeči, že tyto zvukové soubory by měly být staženy s předstihem, což je zpřístupní okamžitě, jakmile se rozhodneme je přehrát (jinak by došlo ke zpoždění při prvním přehrání budíku, než by byly staženy). Přehrávání zvukového souboru je extrémně jednoduché díky HTML5 audio API JavaScriptu (více o tom v dalším fragmentu).

JQuery

V této části tutoriálu rozšíříme kód jQuery digitálních hodin o podporu a přehrávání budíků. Nebudu vysvětlovat kód, který jsme napsali minule, pouze nové doplňky.

První věc, kterou musíme udělat, je definovat řadu proměnných, důležitých pro fungování alarmů:

assets/js/script.js

var dialog = $('#alarm-dialog').parent(),
    alarm_set = $('#alarm-set'),
    alarm_clear = $('#alarm-clear'),
    time_is_up = $('#time-is-up').parent();

// This will hold the number of seconds left
// until the alarm should go off
var alarm_counter = -1;

Dále musíme zkontrolovat, zda při každém zaškrtnutí update_time() nevyčkává alarm funkce.

// Is there an alarm set?

if(alarm_counter > 0){

    // Decrement the counter with one second
    alarm_counter--;

    // Activate the alarm icon
    alarm.addClass('active');
}
else if(alarm_counter == 0){

    time_is_up.fadeIn();

    // Play the alarm sound. This will fail
    // in browsers which don't support HTML5 audio

    try{
        $('#alarm-ring')[0].play();
    }
    catch(e){}

    alarm_counter--;
    alarm.removeClass('active');
}
else{
    // The alarm has been cleared
    alarm.removeClass('active');
}

Když počítadlo dosáhne 0, znamenalo by to, že bychom měli přehrát zvuk budíku a zobrazit dialog „Čas vypršel“. Všimněte si, že i když vybírám #alarm-ring zvukový prvek s jQuery, přistupuji k prvnímu prvku DOM v kolekci, takže získám přístup k JavaScriptu play() metoda, která je dostupná u audio prvků.

Poslední věcí, kterou zbývá udělat, je zpracovat dialog „Nastavit budík“ a různá tlačítka:

// Handle setting and clearing alamrs

$('.alarm-button').click(function(){

    // Show the dialog
    dialog.trigger('show');

});

dialog.find('.close').click(function(){
    dialog.trigger('hide')
});

dialog.click(function(e){

    // When the overlay is clicked, 
    // hide the dialog.

    if($(e.target).is('.overlay')){
        // This check is need to prevent
        // bubbled up events from hiding the dialog
        dialog.trigger('hide');
    }
});

alarm_set.click(function(){

    var valid = true, after = 0,
        to_seconds = [3600, 60, 1];

    dialog.find('input').each(function(i){

        // Using the validity property in HTML5-enabled browsers:

        if(this.validity && !this.validity.valid){

            // The input field contains something other than a digit,
            // or a number less than the min value

            valid = false;
            this.focus();

            return false;
        }

        after += to_seconds[i] * parseInt(parseInt(this.value));
    });

    if(!valid){
        alert('Please enter a valid number!');
        return;
    }

    if(after < 1){
        alert('Please choose a time in the future!');
        return; 
    }

    alarm_counter = after;
    dialog.trigger('hide');
});

alarm_clear.click(function(){
    alarm_counter = -1;

    dialog.trigger('hide');
});

// Custom events to keep the code clean
dialog.on('hide',function(){

    dialog.fadeOut();

}).on('show',function(){

    // Calculate how much time is left for the alarm to go off.

    var hours = 0, minutes = 0, seconds = 0, tmp = 0;

    if(alarm_counter > 0){

        // There is an alarm set, calculate the remaining time

        tmp = alarm_counter;

        hours = Math.floor(tmp/3600);
        tmp = tmp%3600;

        minutes = Math.floor(tmp/60);
        tmp = tmp%60;

        seconds = tmp;
    }

    // Update the input fields
    dialog.find('input').eq(0).val(hours).end().eq(1).val(minutes).end().eq(2).val(seconds);

    dialog.fadeIn();

});

time_is_up.click(function(){
    time_is_up.fadeOut();
});

Na tomto kódu je několik zajímavých věcí. Všimněte si, jak používám vestavěný validity vlastnost na řádku 35, která existuje pro typ zadávání čísel v moderních prohlížečích. Říká nám, zda je obsahem vstupního pole číslo větší než 0 (nezapomeňte, že mají minimální hodnotu 0).

Další věc, která stojí za zmínku, je způsob, jakým je kód pro dialog alarmu organizován pomocí vlastních událostí. Když show je spuštěna událost, vypočítáme zbývající hodiny, minuty a sekundy poplachu, které se následně vloží do vstupních polí.

Tímto jsou naše krásné digitální hodiny s budíky připraveny! Doufám, že se vám tento rychlý návod líbil a že se vám bude hodit ve vašich vlastních projektech.


No