Календарь на JavaScript

Интерфейс календаря состоит из двух частей:

  1. Шапка, в которой указывается название приложения (Календарь) и осуществляется навигация между годами и месяцами. Изменение текущего года реализовано в виде двух ссылок: ссылки на предыдущий год и ссылки на последующий. В центре указывается текущий год. Аналогичным образом реализовано изменение месяца. Изменение месяца имет одну особенность. Если текущий месяц — январь, то при переходе на предыдущий месяц производится переход на декабрь предыдущего года. Аналогичным образом, если текущий месяц — декабрь, то при переходе на следующий месяц производится переход на январь следующего года. Все ссылки несут одновременно информацию о месяце и годе.
  2. Таблица календаря на один месяц. Таблица календаря имеет заголовок с названиями дней недели. Первым днем в таблице идет понедельник.

В скрипте календаря инициализируются три основных массива данных:

  • months — названия двенадцати месяцев года;
  • monthcountdays — количества дней в месяце;
  • weekdays — сокращенные названия дней недели.

Инициализация массива monthcountdays производится отдельно от массивов moths и weekdays. Предварительно необходимо определить год, для одного из месяцев которого осуществляется построение календаря, так как это необходимо для определения количества дней в феврале. Принцип определения месяца и года основан на поиске в URL текущего HTML-документа названия месяца и номера года. Если в URL название месяца или номер года отсутствуют, то календарь строится на текущие месяц и год.

С точки зрения реализации весь скрипт можно разделить на несколько логических блоков.

  1. Определение текущей даты и сохранение ее значения в переменной currentdate.
  2. Инициализация массива months, содержащего названия двенадцати месяцев года, и массива weekdays, содержащего сокращенные названия дней недели.
  3. Выделение из URL HTML-документа требуемого месяца, для которого будет строиться календарь.
  4. Выделение из URL HTML-документа требуемого года, для которого будет строиться календарь.
  5. Создание объекта даты для первого числа того месяца и года, для которого строится календарь, а затем определение для этой даты дня недели, название которого сохраняется в переменной firstday.
  6. Формирование системы навигации (изменение года и месяца).
  7. Формирование таблица календаря:
    1. формирование заголовка таблицы;
    2. формирование шапки календаря с сокращенными названиями дней недели
    3. формирование первой “пустой” ячейки, если месяц начинается не с понедельника;
    4. формирование ячеек таблицы, соответствующих дням месяца;
    5. формирование последней “пустой” ячейки таблицы, если месяц не заканчивается в воскресенье.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Календарь</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
</head>
<body>
    <script type="text/javascript">
    <!--
        var i;
        var currentdate = new Date();

        var months = new Array( "Январь", "Февраль", "Март", "Апрель", "Май", "Июнь",
                       "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь" );
        var weekday = new Array( "Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс" );

        var currentmonth = currentdate.getMonth();
        for(i=0;i<12;i++) {
            if( document.location.href.indexOf( encodeURIComponent(months[i]) ) != -1 ) {
                currentmonth = i;
            }
        }

        var currentyear  = currentdate.getFullYear();
        for(i=1900;i<2100;i++)
            if( document.location.href.indexOf( (new Number(i)).toString() ) != -1 )
                currentyear = i;

        var monthcountday = new Array( 31, (((currentyear%4) == 0 ) ? 29 : 28),
                                       31, 30, 31, 30, 31, 31, 30, 31, 30 ,31 );
         
        var firstday = ((new Date(currentyear,currentmonth,1)).getDay()+6)%7;

        document.write( "<h1 style='text-align:center'>Календарь</h1>"
                        + "<div align='center'>"
                       
                        + "<div><a href='calendar.html?"+encodeURIComponent(months[currentmonth])+","+(currentyear-1)+"'>"+(currentyear-1)+"</A>&nbsp;&nbsp;&nbsp;&nbsp;"
                        + "<strong>" + currentyear + "</strong>"
                        + "&nbsp;&nbsp;&nbsp;&nbsp;<a href='calendar.html?"+encodeURIComponent(months[currentmonth])+","+(currentyear+1)+"'>"+(currentyear+1)+"</a></div>"

                        + ((currentmonth!=0) ? "<div><a href='calendar.html?"+encodeURIComponent(months[currentmonth-1])+","+currentyear+"'>"+months[currentmonth-1]+"</a>&nbsp;&nbsp;&nbsp;&nbsp;"
                                             : "<div><a href='calendar.html?"+encodeURIComponent(months[11])+","+(currentyear-1)+"'>"+months[11]+" of "+(currentyear-1)+"</A>&nbsp;&nbsp;&nbsp;&nbsp;")
                        + "<strong>" + months[currentmonth] + "</strong>"
                        + ((currentmonth!=11) ? "&nbsp;&nbsp;&nbsp;&nbsp;<a href='calendar.html?"+encodeURIComponent(months[currentmonth+1])+","+currentyear+"'>"+months[currentmonth+1]+"</a></div>"
                                              : "&nbsp;&nbsp;&nbsp;&nbsp;<a href='calendar.html?"+encodeURIComponent(months[0])+","+(currentyear+1)+"'>"+months[0]+" of "+(currentyear+1)+"</a></div>")

                        + "</div>" );

        document.write ( "<table width='300' align='center' border='1' bgcolor='#EEEEEE'><tr>" );

        for(i=0;i<7;i++)
            document.write( "<th bgcolor='blue'><span style='color:white'>" + weekday[ i ] + "</span></th>" );

        if( firstday != 0 )
            document.write( "</tr><tr align='center'><td colspan='" + firstday + "'>&nbsp;</td>" );

        for(i=0;i<monthcountday[currentmonth];i++)
        {
            if((i+firstday)%7==0)
                document.write ( "</tr><tr align='center'>" );
            document.write( "<td>" + (i+1) + "</td>" );
        }

        if( (monthcountday[currentmonth]+firstday)%7 != 0 )
            document.write( "<td colspan='" + (7-((monthcountday[currentmonth]+firstday)%7)) + "'>&nbsp;</td>" );

        document.write( "</tr></table>" );
    //-->
    </script>

</body>
</html>

Комментариев: 2

  1. Александр:

    Доброго времени суток! Календарь отличный, код простой.
    Но у меня есть некоторая задача, думаю довольно популярная для календарей.. Каким образом можно привязывать к дате определенную страницу html? Т.е. допустим 9-е мая праздник, для этого в календаре необходимо выделить эту дату определенным цветом и создать для нее ссылку.
    Может быть вопрос и дилетантский, но я только-только начал учить Javascript. Если хотя бы намекнете как, то буду премного благодарен!
    А вообще, посмотрев набор скриптов и т.п. сложилось очень хорошее впечатление о вас. Думаю что-то из ваших работ может пригодиться в будущем. …сайт добавил в закладки ))

  2. Semen:

    Да, у меня такая же задача: нажав на выбранный день в календаре, в окне фрейма дожна открыться соответствующая страница новостей. Сам програмный механизм реализации я знаю, а вот реализовать на javascript - знаний маловато.

Оставьте свой отзыв