Jak vyrobit digitální hodiny s jQuery a CSS3

Všechno to začalo minulý týden, když jsem viděl tuhle pěknou střelu. Okamžitě jsem pocítil nutkání převést je na fungující hodiny a sdílet je se čtenáři Tutorialzinu. Pokud se chcete dozvědět, jak jsem to udělal, čtěte dál!

Značky

Hodiny nepotřebují mnoho HTML. Je tomu tak proto, že jeho velká část, stejně jako názvy dnů v týdnu a kódy číslic, je generována dynamicky. Zde je označení, které musíte mít na své stránce, abyste mohli používat hodiny:

index.html

<div id="clock" class="light">
    <div class="display">
        <div class="weekdays"></div>
        <div class="ampm"></div>
        <div class="alarm"></div>
        <div class="digits"></div>
    </div>
</div>

Hlavní prvek, #clock div, obsahuje .display, který zase obsahuje seznam dnů v týdnu, AM/PM label ikonu budíku a čas. A zde je vygenerovaná značka pro jednu z číslic:

<div class="zero">
    <span class="d1"></span>
    <span class="d2"></span>
    <span class="d3"></span>
    <span class="d4"></span>
    <span class="d5"></span>
    <span class="d6"></span>
    <span class="d7"></span>
</div>

Prvek .digits bude obsahovat 6 těchto divů s rozsahy, jeden pro každou číslici času. Jak můžete vidět z fragmentu výše, tyto divy dostávají název třídy od nuly do devíti (více o tom za sekundu) a obsahují sedm prvků span s jedinečnými třídami. Tato rozpětí jsou segmenty číslic, jako ve starých digitálních hodinách:

Jsou stylizovány výhradně pomocí CSS a jsou nastaveny na opacity:0 ve výchozím stavu. Třída přiřazená k jejich nadřazenému prvku div je dělá viditelnými. Zde je CSS pro nulu:

assets/css/styles.css

/* 0 */

#clock .digits div.zero .d1,
#clock .digits div.zero .d3,
#clock .digits div.zero .d4,
#clock .digits div.zero .d5,
#clock .digits div.zero .d6,
#clock .digits div.zero .d7{
    opacity:1;
}

Všechny segmenty jsou viditelné, kromě prostředního (jinak by to byla 8). Do všech těchto rozsahů jsem přidal vlastnost přechodu CSS3, která animuje neprůhlednost při přepínání mezi čísly.

V šabloně stylů je spousta dalších CSS, ale nebudu je zde uvádět. Domnívám se, že nejlepší způsob, jak se naučit, jak CSS funguje, je prohlédnout si živý kód ukázky ve Firebugu, Chrome's Inspector nebo vývojářských nástrojích vašeho prohlížeče.

Kód jQuery

Aby hodiny fungovaly, budeme muset použít jQuery ke generování označení pro každou z číslic a nastavit časovač pro aktualizaci tříd každou sekundu. Abychom si usnadnili život, použijeme knihovnu moment.js (rychlý tip), abychom kompenzovali chybějící nativní funkce data a času v JavaScriptu.

assets/js/script.js

$(function(){

    // Cache some selectors

    var clock = $('#clock'),
        alarm = clock.find('.alarm'),
        ampm = clock.find('.ampm');

    // Map digits to their names (this will be an array)
    var digit_to_name = 'zero one two three four five six seven eight nine'.split(' ');

    // This object will hold the digit elements
    var digits = {};

    // Positions for the hours, minutes, and seconds
    var positions = [
        'h1', 'h2', ':', 'm1', 'm2', ':', 's1', 's2'
    ];

    // Generate the digits with the needed markup,
    // and add them to the clock

    var digit_holder = clock.find('.digits');

    $.each(positions, function(){

        if(this == ':'){
            digit_holder.append('<div class="dots">');
        }
        else{

            var pos = $('<div>');

            for(var i=1; i<8; i++){
                pos.append('<span class="d' + i + '">');
            }

            // Set the digits as key:value pairs in the digits object
            digits[this] = pos;

            // Add the digit elements to the page
            digit_holder.append(pos);
        }

    });

    // Add the weekday names

    var weekday_names = 'MON TUE WED THU FRI SAT SUN'.split(' '),
        weekday_holder = clock.find('.weekdays');

    $.each(weekday_names, function(){
        weekday_holder.append('<span>' + this + '</span>');
    });

    var weekdays = clock.find('.weekdays span');

    // Run a timer every second and update the clock

    (function update_time(){

        // Use moment.js to output the current time as a string
        // hh is for the hours in 12-hour format,
        // mm - minutes, ss-seconds (all with leading zeroes),
        // d is for day of week and A is for AM/PM

        var now = moment().format("hhmmssdA");

        digits.h1.attr('class', digit_to_name[now[0]]);
        digits.h2.attr('class', digit_to_name[now[1]]);
        digits.m1.attr('class', digit_to_name[now[2]]);
        digits.m2.attr('class', digit_to_name[now[3]]);
        digits.s1.attr('class', digit_to_name[now[4]]);
        digits.s2.attr('class', digit_to_name[now[5]]);

        // The library returns Sunday as the first day of the week.
        // Stupid, I know. Lets shift all the days one position down, 
        // and make Sunday last

        var dow = now[6];
        dow--;

        // Sunday!
        if(dow < 0){
            // Make it last
            dow = 6;
        }

        // Mark the active day of the week
        weekdays.removeClass('active').eq(dow).addClass('active');

        // Set the am/pm text:
        ampm.text(now[7]+now[8]);

        // Schedule this function to be run again in 1 sec
        setTimeout(update_time, 1000);

    })();

    // Switch the theme

    $('a.button').click(function(){
        clock.toggleClass('light dark');
    });

});

Nejdůležitější částí kódu je zde update_time funkce. Uvnitř dostáváme aktuální čas jako řetězec a používáme jej k vyplnění prvků hodin a k nastavení správných tříd na číslice.

Tím jsou naše digitální hodiny připraveny! Podívejte se na další část, kde přidáváme podporu pro nastavení budíků a jejich přehrávání se zvukem HTML5.