Глаза страшат, а руки делают

Велик могучим русский языка
О программировании русских склонений в скриптах, содержащих смену даты или времени
ЧАСТЬ ВТОРАЯ


В первой редакции предыдущая статья заканчивалась небольшим послесловием с описанием функции countdown(), обратной countup(). В ней обнаружились некоторые «дизайнерские» неудобства, несущественные в первоначальной функции. Я немного доработал эти функции, сделав их мобильнее в использовании, о чём и хочу рассказать.

Но сначала воспроизведу текст бывшего послесловия о функции countdown() в её, так сказать, первозданном виде, чтобы уткнуться носом в эту проблему. А затем предложу вариант её решения.

Текст послесловия

Очень просто сделать функцию, обратную этой, которая считала бы дни до события. Чтобы функция завелась в обратном направлении, достаточно либо строчку d = difference.toString(10) заменить на d = (-difference).toString(10), либо document.write("Вот это было создано " + d + a + " назад.") заменить на document.write(-d + a).

Можно назвать эту функцию, скажем, countdown(yr,m,dy), соответственно заменив это в скрипте.

Можно и повыделываться. Например, чаще всего встречаются формулировки «осталось 15 дней» или «остался 41 день». Для этого можно ещё подточить функцию. Например, к букету наших переменных a, b, c, d добавить ещё e, а перед нашим циклом if вставить ещё один, такой:

if (c == 1 && d.length != 1){e = "осталось "}
    else {
    if (b == 1){e = "остался "}
        else {
        e = "осталось "
             }
         }

И, соответственно,

document.write(e + -d + a );

А что же делать, если «час Х» пробил, а у вас не было возможности зайти на сайт и подтереть за собой? Так и будем в минус считать?

Для этого предлагаю сделать так: Не просто document.write(), а

if (difference == 0) {document.write("свершилось!")}
    else {
    if (difference > 0) {document.write("")}
        else {
        document.write(e + -d + a );
             }
         }	

Или просто:

if (difference >= 0) {document.write("")}
    else {
    document.write(e + -d + a );
         }

Обратите внимание: поскольку в функции мы манипулируем с -d или (-difference), то для выводимого отрицательного значения difference должна быть больше нуля.

Но, увы, этот текст, который выводит скрипт, можно форматировать только в теле функции, в document.write(). Например, чтобы на одной странице вывести

До фестиваля осталось

15

ДНЕЙ

а на другой —

Спешите! Осталось только 15 дней!

нужно писать два разных скрипта с этой функцией (и лучше даже дать ей разные имена).

Решение проблемы

Итак мы видим, что проблема в том, как вынести document.write() за пределы этой функции и начинять чем угодно, используя один и тот же скрипт.

Если попробовать механически вывести document.write() из тела функции, то будет генерироваться ошибка отсутствия определения. Выход на самом деле очень простой:

  1. поставить определения наших переменных (var a, b, c, d, e) не в теле, а перед телом функции;
  2. добавить к ним ещё две, например, dd и result (для чего — объясню в процессе);
  3. отредактировать окончание функции (возвращение параметров).

Вот как будет выглядеть начало скрипта:

<script type="text/javascript">

<!-- Begin
var montharray=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug",
"Sep","Oct","Nov","Dec");
var a, b, c, d, e, dd, result;

function countdown(yr,m,dy) {

// далее - тело функции...

Переменная result возьмёт на себя значение содержимого document.write(). Окончание функции будет таким:

dd = difference
if (dd == 0) {result = "свершилось!"} // или что-нибудь Ваше
    else {
    if (dd > 0) {result = ""}
        else {
        result = e + -d + a
             }
         }	
} // скобка, закрывающая всю функцию

//  End  -->
</script>

Стоп! А что тут делает dd?

Сейчас объясню, только будьте внимательны. Мы же пробуем написать функцию «на все случаи жизни». То есть, можем выводить сразу весь текстоый блок — осталось столько-то дней (переменная result), а можем разбирать его на «кубики конструктора». Например, «осталось всего столько-то и только столько-то дней», то есть (e + "всего " + -d + " и только " + -d + a).

Когда пробьёт «час Х», желательно, чтобы это дело самоустранилось. Если мы используем result, то это уже прописано в нашей функции. Если же мы используем конструкцию из «кубиков», то её удаление нужно указать в скрипте «на месте происшествия». Удаление должно произойти, если difference равна или больше нуля (или только если больше нуля, это уже Вам решать).

Но если мы в скрипте «местного значения» помянем difference, то нас «не поймут-с, Азия-с». Потому что эта переменная была объявлена внутри функции, а значит, после закрывающей функцию фигурной скобки она «приказала долго жить». Если же мы вынесем её объявление за функцию, то потребуется ещё много чего объявлять — «бабка за дедку, дедка за репку», и функция… «какой ужас, какой кошмар, какие мелкие кусочки». Поскольку переменная difference «выращена» внутри функции и не выживет в другой «атмосфере».

Вот поэтому мы и объявляем (перед функцией) переменную dd, чтобы она «прикарманила» значение difference и гуляла с этим значением по всем скриптам (кстати, в самом теле функции можно приравнивать к result хоть difference, хоть dd — это без разницы).

И тогда наши два примера про фестиваль будут выглядеть так:

1)

<script type="text/javascript">
<!--
countdown(2006,08,11)  // или сколько хотите
if (dd >= 0) {document.write("")}
else {document.write("<p align='center' style='margin: 3px;'><b>" + "До
фестиваля " + e + "</p><h2 align='center' style='margin: 3px; color: Red;'>"
+ -d + "</h2><h4 align='center' style='margin: 3px; color: Gray;
text-transform: uppercase;'>" + a +"</h4>")}
//-->
</script>

2)

<script type="text/javascript">
<!--
countdown(2006,08,11)  // или сколько хотите
if (dd >= 0) {document.write("")}
else {document.write("<h3 align='center' style='color: Red;'><i>Спешите!
<span style='text-transform: capitalize;'>" + e + "</span> только " + -d + a
+"!</i></h3>")}
//-->
</script>

Обращаю внимание на маленькие хитрости с использованием стилей: в первом случае, чтобы поменять регистр в слове ДЕНЬ/ДНЯ/ДНЕЙ, мы заключаем переменную a в <h4 style="text-transform: uppercase;">, во втором — аналогично настраиваем заглавную букву в Осталось/Остался (<span style="text-transform: capitalize;"> для переменной e).

Теперь мы можем, ссылаясь на одну-единственную функцию, использовать:

  • разное форматирование;
  • разные варианты текста;
  • разные сроки (поскольку конкретное значение countdown также задаётся «на месте»).

Скачать скрипт (скачано )



 002025