В этом уроке мы создадим с вами такой симпатичный секундомер. Кликая на эту кнопку, секундомер запустится, с помощью этой кнопки мы можем остановить секундомер и с помощью этой кнопки мы можем обнулить данные.
Итак, создадим новый html-файл c именем stopwatch, что в переводе означает секундомер. Далее создадим необходимые начальные теги.
В теге title напишем секундомер. Также пишем секундомер с помощью тега h1 внутри body. Затем набираем тег абзаца. Внутри тега абзаца будут два тега span. У первого тега спэн айди будет seconds, т.е. секунды и пишем 2 нуля, у второго тега span айди будет tens т.е. десятки и также набираем 2 нуля. Следом за абзацем будут три кнопки с id button-start, button-stop и button-reset соответственно. Набираем текст на кнопках.
Далее нам надо напечатать код CSS.
Для начала я хочу создать css-переменную, где будет хранится 16-ричный код оранжевого цвета. Это будет основной цвет программы. Обычно переменные размещаются в псевдоклассе root.
Когда один и тот же цвет применяется в нескольких местах ccs-кода, то я предпочитаю использовать переменные.
Двигаемся дальше. Для тега боди я задам оранжевый цвет фона, шрифт будет либо робото либо любой шрифт без засечек, высота 100%, цвет текста будет белый, и выравниваем весь текст и кнопки по центру.
Для тега h1 увеличим шрифт, сделаем буквы менее жирными и заглавными.
Для тегов span тоже увеличим шрифт.
Для кнопки мы укажем закругление углов, цвет кнопки будет оранжевый, цвет текста белый, сама рамка будет такая, при наведение курсора, курсор будет превращаться в указывающий пальчик, увеличим чуть размер шрифта, отступы и поля будут такие. С помощью вложенности селектором также напишем стиль для тега button с псевдоклассом hover: для начала создадим более плавную анимацию, далее изменим оранжевый цвет кнопки на белый, а текст будет оранжевый. Готово, проверяем. Вроде все красиво. Теперь начинаем набирать код JavaScript.
Разместим тег скрипт перед закрывающим тегом body, чтобы наш код на JavaScript заработал после того как загрузится вся страница. В начале создадим переменные, где будут хранится секунды и милисекунды. Затем создадим переменные, которые будут необходимые объекты, или проще сказать теги из Document Object Model или просто DOM.
И последней переменной у нас будет Interval. Мне она понадобиться, чтобы перезапускать каждые 10 миллисекунд функцию, которая будет добавлять 1 к переменной miliseconds. Вы можете спросить, а почему надо перезапускать функцию каждые 10 миллисекунд, а не 1, или 100 миллисекунд. Напомню что в одной секунде тысяча миллисекунд. И Дело в том что миллисекунды мы отображаем на экране с помощью двух цифр. 01 означает десять миллисекунд. Поэтому функция, которая будет добавлять 1 к миллисекундам, должна перезапускаться каждые 10 миллисекунд.
Двигаемся дальше, а дальше нам надо создать функцию, которая будет перезапускаться каждые 10 миллисекунд. Имя у неё будет startTimer, параметров у функции не будет. А код внутри фигурных скобок напишем такой:
При каждом запуске функции будет прибавляться 1 у переменной miliseconds.
Далее нам нао написать код если переменная miliseconds меньше 10 то будет 0 впереди числа, если больше то нет.
Это мы сделаем с помощью условного оператора if
Тег для миллисекунд хранится в теге appendMiliseconds, но как получить доступ к его значению? К значениям формы мы получали доступ через свойcтво value, а для всех остальных тегов есть свойство innerHTML, которое возвращает все что находится внутри тега в виде текста. Даже если внутри тега находятся другие теги, он их вернет в виде текста. Итак, пишем innerHTML, сперва будет идти 0 а потом значение переменной miliseconds. В противном случае нуля не будет.
Далее нам нужно создать код, который будет прибавлять 1 к секундам и сбрасывать в 0 миллисекнды, когда значение миллиекунд дойдет до 100.
Т.е. если значение миллисекунд больше 99, то сбрасываем в ноль эту переменну, и также сбрасываем значение на экране. Далее прибавляем 1 к секундам, и давайте создадим такой же код для отображения нуля с переди как мы делали это в миллисекундах. Мы можем написать это за пределами этого if, но можем и внутри, от этого смысл не потеряется. Так что давайте внапишем его внутри этого if.
Да, проще воспринимается, если бы эти два if были отдельно, но я хотел показать что и так можно писать. И давайте еще, когда выполнится этот двойной if выведем сообщение в консоль. Это в принципе не нужно для секундомера, но я решил, что это хороший момент освоить данный примем. Итак, для взаимодействия с конслью браузера, в javascript есть такой заготовленный объект console у которого есть много методов, с помощью которых мы и можем взаимодействовать с консолью. И метод благодаря которым мы можем выводить сообщения в консоль называется log, где внутри скобок вы можете поместить что угодно, что нужно вывести в консоль: это может быть текст, число, массив, объект и т.д. У на будет текст “Этот двойной if выполнился”
Напишем этот код например перед закрывающей скобкой данного if. Да здесь легко запутаться в фигурных скобках, но на помощь может прийти программы которая подсказываем кому принадлежит та или иная фигурная скобка. Надо просто поставить курсор спереди или сзади фигурной скобки. Вот как видите консоль показывает что эта фигурная скобка принадлежит данному if.
Итак. функция готова. Теперь нам надо ее запускать каждые 10 миллисекунд когда пользователь кликнет по кнопке Старт.
Пишем необходимую переменную, где содержится наша кнопка в виде объекта. Далее через точку мы имеем доступ к атрибуту onclick, в значении которой мы должны указать функцию, которая будет вызываться, когда пользователь будет кликать на кнопку. Технически можно указать и не функцию, это не считается ошибкой, но код в большинстве случаем просто не будет работать.
Итак, создадим мы анонимную функцию без параметров, которая будет запускать другую функцию starTimer каждые 10 сек. Но как это сделать. А в этом нам поможет заготовленная функция setInterval, которая позволяет запускать любую вашу функцию через какой-либо промежуток времени. setInteval на самом деле очень прост, первым параметром мы должны написать имя функции, второй параметр будет промежуток времени в миллисекундах, а дальше можем указать аргументы для нашей функции если они нужны.
Возвращаемое значение функции setInterval — это уникальный идентификатор интервала, т.е. имя интервала который задается с помощью присвоения setInterval какой-либо переменной. Т.е. когда мы вызов функции присвоим какой либо переменной, то тогда имя переменной станет именем интервала, которая функция и будет возвращать. А нужно оно нам, чтобы мы могли удалить интервал через его имя
А как же это сделать? Здесь к нам на помощь придёт уже другая заготовленная функция clearInterval в параметре которой мы должны написать имя интервала, который хотим удалить.
Функцию setInteval мы присвоим переменой interval, т.е. теперь функция будет возвращать свое имя как interval. В первом параметре напишем имя нашей функции, в вторым параметром будет 10 миллисекунд. Давайте проверим, вроде работает, только проблема в том , что если мы несколько раз нажмем на старт, то ускорится время на секундомере. Дело в том, что когда мы несколько раз жмём на кнопку старт, каждый раз функция setInterval создает новый таймер, который вызывает нашу функцию StartTimer и все эти таймеры существуют параллельно, увеличивая количество вызовов функции каждые 10миллисекунд.
Как это исправить? было бы хорошо, если при нажатии на кнопку start программа проверяла есть ли уже запущенный интервал с определенным именем, и если да, удалить этот интервал и запустить заново.
Давайте сделаем это. В условии проверим содержит ли переменная какой либо интервал. Если она не будет равна undefined значит содержит, а если содержит, то давайте его удалим. Теперь получается при каждом нажатии на кнопку старт, будет удаляться существующий интервал, если он есть, и запускаться заново. Можно также написать этот код без if, так как если у переменной нет никакого интервала, то функция clearInterval просто не будет ничего делать.
Кстати, помните я говорил, что в JavaScript есть базовый объект с именем Object, от которого мы наследуем свойства и методы. Так вот, разработчики браузеров решили, что базовый объект не содержит все необходимые методы для работы с браузером, поэтому они изобрели так называемый глобальный объект window, который также наследует свойства и методы базового объекта.
На самом деле у объекта window длинная цепочка прототипов, так как объект window является прототипов объекта Window, но теперь название пишется с большой буквы. Почему некоторые объекты пишутся с большой, а некоторые с маленькой буквы вы узнаете уже на следующем уроке. Для Window прототипом является EventTarget, а уже для EventTarget прототипом является базовый объект Object. Итак ввернемся к window с маленькой буквы.
А почему объект window назвали глобальным объектом? Дело в том что весь наш код, который мы создаем, как бы находится внутри объекта window все переменные и функции являются свойствами и методами объекта window. Это касается и заготовленных функций, все они тоже методы объекта window, а значит мы можем написать так. Но здесь важно уточнить, ваши переменные будут являться свойствами и методами глобального объекта window, если они были объявлены с помощью ключевого слова var. Если вы создадите функцию, то она станет методом объекта window, а если вы создадите переменную с помощью ключевого слова let, и в значении создадите функцию, то эта переменная не станет методом window. Это происходит из-за видимости переменных, о которой мы поговорим в одном из следующих уроков.
Запускаем, теперь скорость времени на секундомере не меняется.
Теперь давайте настроим кнопку стоп при клике на которую будет просто удаляться интервал. Здесь я уже обойдусь без проверки, содержит ли переменная интервал, который надо удалить, а просто сразу напишу функцию.
Проверяем. Как видите функция перестала запускаться.
Теперь настроим кнопку Сброс, где мы не только удалим интервал, но и очистим все данные.
Секундам и миллисекундам назначим нули, а также сбросим текст внутри тегов. Проверяем. Все работает. Давайте проверим также консоль. Как видите наше сообщение появляется и слева показывается сколько раз оно появляется.
Домашнее задание. Давайте усовершенствуем наш секундомер. Удалим кнопку стоп и сделаем так: при клике на кнопку старт запускается таймер, и текст на кнопке меняется на Стоп. Далее если мы кликнем снова по этой кнопке то таймер остановится и кнопка снова поменяет название на старт. Подсказка, вы можете создать числовую переменную, благодаря которой можете отслеживать запустил ли пользователь таймер или остановил. Удачи!