Стать программистом. Практика JavaScript для новичков. Занятие 3.


Доброго времени суток, друзья!

В нашем прошлом занятии мы развернули необходимые для работы исходники, познакомились с файловой структурой нашего проекта, рассмотрели основную логику разбиения кода на три js-файла и соответственно на три основных сущности : {Booth}, {Brain} и (Pet), узнали о том, что взаимодействовать эти составляющие будут через Глобальную Область Видимости, привели доводы почему в случае нашей практики мы можем использовать глобальное пространство JavaScript’a, и конечно же приступили к непосредственному оживлению нашей статической картинки с помощью кода. Начали мы с таймеров (прогрессбаров) с характеристиками нашего питомца, и пока написали функцию для их уменьшения.

Давайте продолжим!

Стать программистом. Практика JavaScript для новичков. Занятие 3.

Итак, наш код внутри объекта {Booth} сейчас имеет следующий вид:

Функция runProgressBar() делает свою работу и уменьшает наш счетчик. В предыдущем уроке мы поставили перед собой две задачи для реализации:

  1. Реализовать функциональность чтобы счетчики уменьшались с течением времени.
  2. Чтобы в зависимости от того, на сколько они уменьшились, менялся бы цвет их фона.

Можно сказать, что с первой мы справились. Теперь давайте посмотрим, как реализовать задачу со сменой фона. Ну с моментом, когда именно фон должен будет смениться я думаю проблем у нас не возникнет. В нашей функции для уменьшения ширины счетчика мы используем переменную width, которая и будет индикатором для смены. Когда её значение станет равным 50 мы должны будем поменять цвет фона у счетчика на оранжевый, а когда её значение станет 25 – на красный. Давайте добавим в нашу функциональность эту проверку.

Обратите внимание на то, как мы преобразовали нашу функцию по уменьшению ширины счетчика. В первую часть проверки, где непосредственно идет присвоение новой ширины счетчику мы добавили два оператора if(){}. Первый проверяет значение переменной width и смотрит, что если это значение меньше либо равно 50, то выведет сообщение в консоль браузера о наступлении «оранжевого момента». Второй условный оператор делает то же самое, только сравнение идет с величиной 25 и сообщение уже о «красном моменте».

Кроме этого, посмотрите, что вместо миллисекунд во втором параметре нашего интервала я жестко задал цифру 200. Это временно, просто для того, чтобы счетчик уменьшался быстрее чем раз в секунду, и мы скорее могли проверить все ли мы сделали верно. Давайте вызовем нашу функцию по уменьшению ширины применительно ко второму счетчику (второй параметр секунды мы можем пока не передавать, так как жестко прописали время - 200):

Вот что мы получаем. Когда счетчик падает по 50%, нам каждые 200 миллисекунд начинает выдаваться сообщение о том, что наступил «оранжевый момент» (что верно, так как переменная width будет один раз равна 50 и потом всегда меньше, то есть условие для первого оператора выполняется), а когда её значение упадет до 25 мы будем видеть уже два сообщения, потому что будут выполнятся уже оба условия. Это в общем-то решает нашу задачу с поимкой момента для изменением цвета, но коряво и много мусора. Зачем нам каждый интервал времени выводить сообщение? Незачем. Как бы нам решить эту проблему?

Первый и самый простой способ ввести для каждого счетчика так называемые флаги. Эти флаги – свойства, значением которых будет булевский тип (Boolean). Сначала флаг имеет значение false (событие еще не наступило), а когда событие наступает, он меняет свое значение на true. И мы можем воспользоваться таким подходом для решения нашей задачи:

var Booth = {
    timer1: {
        selector: document.getElementById('fatigue'),
        isOrange: false,
        isRed: false
    },
    timer2: document.getElementById('satiety'),
    timer3: document.getElementById('mood'),
    /* Запускаем счетчики парметров */
    runProgressBar: function(timer, seconds) {
        var width = 100;
        var milliseconds = seconds*1000;
        var interval = setInterval(function() {
            if(width != 0) {
                width -= 1;
                timer.selector.style.width = width + '%';

                /* смена цвета счетчика*/

                if(timer.isOrange == false && width <= 50) {
                    timer.isOrange = true;
                    console.log('оранжевый');
                }

                if(timer.isRed == false && width <= 25) {
                    timer.isRed = true;
                    console.log('крассный');
                }

            } else {
                clearInterval(interval);
            }
        }, 200);
    },
}

Давай разбираться что же мы преобразовали. Во-первых наш первый таймер превратился из обычной выборки в Объект (обведен зеленой рамкой). Для сравнения два других таймера пока остались в прежнем состоянии. В новый объект мы перенесли нашу выборку в свойство selector. И так как выборка сместилась на 1 уровень вниз, то и работа с ней в нашей функции по изменению ширины немного преобразится (проследите за сиреневой линией). Кроме того, мы завели два флага: для оранжевого момента isOrange, который мы добавили в наш условный оператор с величиной 50 (следите за оранжевой линией) и для красного момента - isRed, который мы разместили в условном операторе с величиной 25 (следите за красной линией).

То есть логика следующая. Сначала isOrange равен false (то есть событие еще не наступило) и условие timer.isOrange == false && width <= 50 будет выполнятся. Однако, как только переменная width станет равна 50-ти, мы изменим наш флаг на значение true с помощью кода расположенного на 21 линии. И после этого условие timer.isOrange == false && width <= 50 уже не будет выполнятся, так как наш первая часть этого условия timer.isOrange == false … будет неверной. Как следствие мы должны будем увидеть сообщение о наступлении «оранжевого момента» только один раз. Точно такая же логика работает с флагом isRed. Давайте, запустим наш код в консоли браузера и убедимся, что все хорошо:

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

var Booth = {
    timer1: {
        selector: document.getElementById('fatigue'),
        isOrange: false,
        isRed: false
    },
    timer2: {
        selector: document.getElementById('satiety'),
        isOrange: false,
        isRed: false
    },
    timer3: {
        selector: document.getElementById('mood'),
        isOrange: false,
        isRed: false
    },
    /* Запускаем счетчики парметров */
    runProgressBar: function(timer, seconds) {
        var width = 100;
        var milliseconds = seconds*1000;
        var interval = setInterval(function() {
            if(width != 0) {
                width -= 1;
                timer.selector.style.width = width + '%';

                /* смена цвета счетчика*/

                if(timer.isOrange == false && width <= 50) {
                    timer.isOrange = true;
                    console.log('оранжевый');
                }

                if(timer.isRed == false && width <= 25) {
                    timer.isRed = true;
                    console.log('крассный');
                }

            } else {
                clearInterval(interval);
            }
        }, 200);
    },
}

Двигаемся дальше. И теперь мы приступим непосредственно к самому изменению цвета. Логично, что енять мы его будем в момент, где сейчас у нас выводятся сообщения (строки 30 и 35). Реализовать это с помощью JavaScript можно несколькими способами. Первый из них – так же как в случае с шириной напрямую использовать сss свойство. У каждого html элемента есть свойство background. Оно отвечает за цвет фона. Если мы воспользуемся инспектором, то найдем его тут:

И точно так же, как и в случае с шириной мы можем поменять его прямо ручками в браузере и посмотреть, что из этого выйдет:

Как видим, цвет фона меняется. Давайте добавим такое изменение внутри нашего кода.

var Booth = {
    timer1: {
        selector: document.getElementById('fatigue'),
        isOrange: false,
        isRed: false
    },
    timer2: {
        selector: document.getElementById('satiety'),
        isOrange: false,
        isRed: false
    },
    timer3: {
        selector: document.getElementById('mood'),
        isOrange: false,
        isRed: false
    },
    /* Запускаем счетчики парметров */
    runProgressBar: function(timer, seconds) {
        var width = 100;
        var milliseconds = seconds*1000;
        var interval = setInterval(function() {
            if(width != 0) {
                width -= 1;
                timer.selector.style.width = width + '%';

                /* смена цвета счетчика*/

                if(timer.isOrange == false && width <= 50) {
                    timer.isOrange = true;
                    timer.selector.style.background = 'orange';
                }

                if(timer.isRed == false && width <= 25) {
                    timer.isRed = true;
                    timer.selector.style.background = 'red';
                }

            } else {
                clearInterval(interval);
            }
        }, 200);
    },
}

По аналогии с тем как мы меняли css-свойство width теперь мы меняем css-свойство background. В первом случает на цвет orange (оранжевый), во втором – на red красный.
Проверим как это отработает в браузере:

Все хорошо, только цвет названия счетчика выполнен белым, и он теряется на белом фоне. Давайте немного исправим этот нюанс тем, что в момент смены фона счетчика, поменяем так же и цвет текста внутри него. Делается это точно также, как в случае с width и background. Только за цвет фона у нас отвечает css-свойство, которое называется color.

var Booth = {
    timer1: {
        selector: document.getElementById('fatigue'),
        isOrange: false,
        isRed: false
    },
    timer2: {
        selector: document.getElementById('satiety'),
        isOrange: false,
        isRed: false
    },
    timer3: {
        selector: document.getElementById('mood'),
        isOrange: false,
        isRed: false
    },
    /* Запускаем счетчики парметров */
    runProgressBar: function(timer, seconds) {
        var width = 100;
        var milliseconds = seconds*1000;
        var interval = setInterval(function() {
            if(width != 0) {
                width -= 1;
                timer.selector.style.width = width + '%';

                /* смена цвета счетчика*/

                if(timer.isOrange == false && width <= 50) {
                    timer.isOrange = true;
                    timer.selector.style.background = 'orange';
                    timer.selector.style.color = 'black';
                }

                if(timer.isRed == false && width <= 25) {
                    timer.isRed = true;
                    timer.selector.style.background = 'red';
                }

            } else {
                clearInterval(interval);
            }
        }, 200);
    },
}

Мы добавили необходимую строку кода, теперь используя свойство color. Нам достаточно чтобы цвет изменился только один раз в момент наступления первой смены фона. Во второй раз этого делать не требуется так как черный текст и на оранжевом, и на красном фоне вполне заметен. Давайте взглянем на результат:

Безусловно есть нюансы, но в целом мы добились того, чего хотели и наш счетчик теперь не только уменьшается, но и меняет цвет на определенных этапах.

А на сегодня все. Продолжение следует…

Ссылки на предыдущие занятия:

Практика JavaScript для новичков. Занятие 1,

Практика JavaScript для новичков. Занятие 2,

Ссылки на предыдущий курс:

Урок 1 - Окружение.,

Урок 2 - Некоторые особенности синтаксиса.,

Урок 3 - Переменные.,
Урок 4 - Типы переменных, как основа для их взаимодействия.,
Урок 5 - Операции с переменными одного типа.,
Урок 6 - Операции с переменными одного типа. Часть II.,
Урок 7 - Взаимодействие переменных с разными типами.,
Урок 8 - Взаимодействие переменных разного типа. часть II.,
Урок 9 - Взаимодействие переменных разного типа. Часть III.,
Урок 10 - Другие возможные взаимодействия между переменными.,
Урок 11 - Другие возможные взаимодействия между переменными. Часть II.,
Урок 12 - Другие возможные взаимодействия между переменными. Операторы присваивания.,
Урок 13 - Другие возможные взаимодействия между переменными. Операторы сравнения.,
Урок 14 - Сложные переменные. Array и Object.,
Урок 15 - Условные операторы.),
Урок 16 - Циклы.,
Урок 17 - Циклы. Часть II.,
Урок 18 - Функции.,
Урок 19 - Функции. Часть II.,
Урок 20 - Профилирование. Функции, часть III.,
Урок 21 - Функции, Часть IV. Аргументы.,
Урок 22 - Objects (Объекты).,

Урок 23 - Встроенные функции и объекты.,
Урок 24 - Встроенные функции и Объекты, Часть II. Глобальные функции и переменные.,
Урок 25 - Встроенные функции и Объекты, Часть III. Document Object Model.,
Урок 26 - Встроенные функции и Объекты, Часть III. Document Object Model.
Урок 27 - Встроенные объекты. Объект Style, Events, Часть II.
Урок 28 - Встроенная переменная this. Глобальная и локальная области видимости.
Урок 29 - Объектно-ориентированное Программирование. Введение.
Урок 30. Объектно-ориентированное Программирование. Часть II. Полиморфизм.
Урок 31. OОП. Наследование, Часть I. Оператор new.
Урок 32. ООП. Наследование, Часть II. PROTOTYPE.
Урок 33. ООП. Часть II. Полиморфизм.
Урок 34. ООП. Часть III. Инкапсуляция.


Comments 2