Знакомство с JavaScript — Тренажёр HTML Academy
Продолжаем глубже знакомиться с веб-разработкой и по программе тренажёров HTML Academy на очереди у нас идет JavaScript, который уже не вёрстка, а язык программирования.
В позапрошлом блоке мы легонечко уже «знакомились» с JS, там мы искали элементы и меняли им классы с помощью простого обработчика событий, что даже так меня впечатлило как туземца вертолёт.
Я чутка поэкспериментирую со статьями, попробую вернуться к формату «один блок — одна статья», как и было сначала, но постараюсь сократить растекания мыслей по древу.
Часть 1: Условия и создание элементов
В прошлый раз нам надо было найти элемент и поменять ему класс, таким образом поменяв тему сайта, теперь задачка масштабами меньше, но функционально посложнее — нам надо прикрутить лайки!
Лайки
По нажатию на кнопку лайка одновременно происходит несколько событий. Идем от общего к частному — индикатор лайка заполняется, а счетчик количества лайков увеличивается на один.
Для работы нам нужен сам элемент с индикатором, подготовить для него два стиля — пустой (по умолчанию) и заполненный, а также элемент счетчика с одним классом — у него меняется значение, а не состояние.
Находим наши элементы и объявляем переменные:
let heart = document.querySelector('.heart'); let likesNumber = document.querySelector('.likes-number');
С обработчиком событий по клику .onclick
мы знакомы и как менять классы classList.toggle
мы тоже уже знаем, с индикатором всё понятно. В счетчике меняется число, то бишь контент .textContent
, его мы тоже уже знаем.
Что мы пока не знаем — это как увеличить число лайков на один, а не просто поменять на произвольный контент. Это сделать можно несколькими способами:
num = num + 2 // полная запись num += 2 // короткая запись num++ // увеличение на 1 ("+= 1" или "num + 1")
Нам подходят все, но последний как раз придуман умными дядьками для таких задач как наша. Видимо, очень часто надо именно «+1». В итоге получается:
heart.onclick = function () { likesNumber.textContent++; // прибавляем лайк heart.classList.toggle('added'); // заполняем индикатор };
Но у нас проблема! Индикатор-то работает в обе стороны, а вот счетчик прибавляет, но не убавляет количество при снятии лайка. Идем, опять же, от общего к частому. Если индикатор пустой — нужно прибавить, если заполнен — убавить. Теперь надо это написать на языке JS.
В этом нам поможет метод classList.contains()
, который проверяет наличие класса в указанном элементе и возвращает True или False, то есть «Верно» или «Неверно». С этим методом и условными операторами if (условие) {ф-ция}
и else {другая ф-ция}
мы можем довести задачу до конца:
heart.onclick = function () { // если (заполнен) if (heart.classList.contains('added')) { likesNumber.textContent++; // прибавить } else { // иначе likesNumber.textContent--; // убавить } heart.classList.toggle('added'); };
Готово! Как оно там работает с сервером, в плане как сохранить кол-во лайков — это я пока не знаю. Пока задачи чисто визуальные.
Комментарий
Следующая задачка — комментарий! Не весь блок комментариев, видимо, это пока сложно для начинающего, а именно реализовать добавление комментария через форму. Наверное, будет нагляднее дать скрин из задания:
Попробуем снова от общего к частому — при оправки определённой формы, нужно создать элемент, добавить его в определённый блок и вписать в этот элемент содержимое определённого поля из этой формы.
Итого нам нужно найти на странице саму форму, поле ввода и сам блок комментариев, а также подготовить стиль для комментария. В данном случае весь блок это нумерованный список <ol> и каждый комментарий — это пункт списка <li>, поэтому с этим мы и будем работать.
Находим и объявляем переменные:
let commList = document.querySelector('.list'); // блок комментариев let commForm = document.querySelector('.form'); // форма let commInput = document.querySelector('.input'); // поле формы
Про обработчик событий при отправке формы .onsubmit
нам вскользь упоминали в прошлый раз, уже хорошо. Тут в задании, правда, какая-то конструкция в виде evt.preventDefault();
— я так понял, что это штука не дает отправить пустую форму, но про нее пока без разъяснений.
С отправкой разобрались, теперь нам нужно каким-то образом создать элемент с помощью JavaScript и нам в этом поможет метод .createElement()
! Наш комментарий это пункт списка <li>, поэтому создадим его и сразу запишем в переменную:
let newComm = document.createElement('li');
Интересно, можно ли метод использовать сразу в какой-то области, а не только в документе? Беглый гуглинг дал понять, что, вроде как, нельзя. Ну и ладно.
Сам элемент создается непонятно где, наверное, в конце документа (?), поэтому теперь нам нужно явно добавить его к уже существующему блоку комментариев. В этом нам поможет метод .append()
, который добавляет к указанному блоку указанный элемент:
commList.append(newComm);
Отлично — мы только что создали и добавили пустоту! Пустой пункт списка <li> без контента и стилей. Что ж, добавлять классы мы умеем, а вот контент нам нужен определенный — из поля формы. Само поле формы мы уже нашли, но нам нужно его значение, то есть value
— его и указываем!
commForm.onsubmit = function (evt) { // отправка формы evt.preventDefault(); // что-то непонятное let newComm = document.createElement('li'); // создаем <li> newComm.classList.add('comment'); // добавляем класс newComm.textContent = commInput.value; // вставляем контент commInput.value = ''; //очищаем поле ввода commentList.append(newComm); // добавляем полученное в блок };
Готово! Очистка поля это бонусное задание, но я думаю и так понятно как оно работает.
Испытание
По поводу практики — её как бы нет, есть только одно испытание и по своей сути — это комбинация того, что мы сейчас проделали. Нужно подправить код, чтобы к списку добавлялся пункт с текстом из формы, раскрашенный в зависимости от переключателя.
Надо сказать интересное задание, пришлось чутка посидеть, попыхтеть. Очень предусмотрительно продублировали задачи в коде.
Часть 2: Коллекции и свойства элементов
Идем дальше в том же духе — нам ставят задачу, мы ее пытаемся исполнить. В этой части продолжаем мучить комментарии, но сначала отвлечёмся на создание всплывающих подсказок или Tooltip.
Tooltip
Ситуация следующая — в тексте статей периодически встречаются термины или высказывания, к которым нужно прикрутить пояснения или комментарий. Появляются они в всплывающем окне, которое за нас уже сверстали. Наша задача сделать так, чтобы при нажатии на определенный термин появлялся именно его tooltip.
Всплывающее окно появляется при добавлении ему класса opened — это мы умеем. Связать нажатие .onclick
по термину с окном мы тоже сможем, надо только найти нужные селекторы терминов и записать в переменные. Верно?
let tooltipButton = document.querySelector('.tooltip-button');
Да, но только если у вас на странице только один такой tooltip, иначе работать будет только первый указанные в вёрстке — остальные не будут. Нам нужно найти их все и в этом нам поможет .querySelectorAll
— который находит все указанные элементы и возвращает их набор или «коллекцию«.
Коллекция представляет собой, грубо говоря, список всех найденных элементов, которым присвоен свой индекс начиная с нуля. Через номер индекса [n], мы можем обращать к каждому в отдельности:
let tooltipButtons = document.querySelectorAll('.tooltip-button'); console.log(tooltipButtons[0]); // выводит первый элемент console.log(tooltipButtons[1]); // выводит второй
Хорошо, получается мы можем найти все элементы с подсказками и каждому прикрутить обработчик .onclick
— тогда всё будет работать? Будет, но в реальности мы никогда не знаем сколько в статье будет таких подсказок и будут ли вообще. Нужно сделать что-то универсальное, не зависящее от точного количества элементов.
Здесь на сцену выходит цикл for of
! Нас предупредили, что циклов в JS много, но конкретно этот выполняет указанный в нём код столько раз, сколько элементов содержится в указанной коллекции. На примере нашей:
let tooltipButtons = document.querySelectorAll('.tooltip-button'); for (let tooltipButton of tooltipButtons) { // условия цикла console.log(tooltipButton); // выводит по очереди все элементы }
Здесь непосредственно в условиях цикла мы объявляем переменную tooltipButton, которой будет присваиваться значение элемента из коллекции tooltipButtons, таким образом код внутри цикла будет исполняться для всех элементов в коллекции. Вписываем туда наш обработчик и получаем:
let tooltip = document.querySelector('.tooltip'); // окно подсказки let tooltipButtons = document.querySelectorAll('.tooltip-button'); for (let tooltipButton of tooltipButtons) { tooltipButton.onclick = function () { tooltip.classList.add('opened'); }; }
Замечательно, мы научились открывать пустое окно для каждого элемента в тексте. Теперь нужно в это окно добавить саму подсказку. И тут в тренажёре про этот нюанс упомянуто вскользь, но на мой взгляд об этом надо было хотя бы как-то упомянуть в блоке про HTML.
Текст подсказки реализован в вёрстке, с помощью эээ… специального, «кастомного» data-атрибута элемента. Оказывается, любым тегам можно задавать свои атрибуты, нужно только поставить префикс data- и называй как удобно. Я очень много встречал сайтов с тонной атрибутов у каждого тега и теперь мне стало понятно почему. Ладно, это потом.
Достать значение такого атрибута можно с помощью метода .dataset.атрибут
, с несколькими нюансами при написании имени атрибута:
- Имя атрибута указывать без префикса data-;
- Если в названии атрибута есть несколько слов и дефисы, то в JS его записывать в «Верблюжьем стиле» — имяАтрибутаПодсказки.
У каждой кнопки с тултипом есть свой атрибут с уникальным значением, нам нужно лишь достать его и запихнуть в текстовое поле всплывающей подсказки. Находим селектор текстового поля, добавляем в наш цикл его замену:
let tooltip = document.querySelector('.tooltip'); // окно подсказки let tooltipText = document.querySelector('.tooltip-text'); // её текст let tooltipButtons = document.querySelectorAll('.tooltip-button'); for (let tooltipButton of tooltipButtons) { tooltipButton.onclick = function () { tooltipText.textContent = tooltipButton.dataset.tooltipText; tooltip.classList.add('opened'); }; }
Отлично, все работает. С этим кодом нам не важно сколько на странице будет тултипов — они все будут работать благодаря циклу. Нужно только добавить кнопку закрытия окна — я ее не стал везде пихать, потому что это просто обработчик .onclick
с методом classList.remove
— мы уже разбирали.
Вообще, насколько я могу судить из того что сам видел — таким образом работают большинство всплывающих окон, конкретно здесь это тултип по клику на слово в тексте, но различные всплывающие формы или «спасибки» после отправки — все делается примерно по такому же алгоритму.
Делаем Twitter
Возвращаемся к комментариям! Задача ограничить количество символов при отправке комментария до 142. Для нас сверстали счётчик в виде специального элемента <output> и добавили класс warning предназначенное для формы.
Итак, из предыдущей части у нас уже есть код обрабатывающий отправку сообщений. Для начала, нам нужно как-то понять сколько символов введено в поле в данный момент.
Для этого мы используем новый обработчик событий .oninput
— который выполняет указанный в нем код каждый раз когда изменяется значение в указанном поле. Таким образом мы можем «отследить» ввод, теперь нам надо узнать количество символов.
Для этого мы используем свойство .length
которое как раз передает число символов в строке. Мы применим его для value поля ввода, получаем:
commInput.oninput = function () { // обработчик ввода console.log(commInput.value.length); // выводит текущее число символов };
Хорошо, ключевое число символов мы нашли. Теперь нужно создать конструкцию, которая, во-первых, не позволит отправить сообщение если оно превышает указанное, во-вторых наглядно вывести текущее число символов и применить предупреждающий стиль warning для формы.
Область комментариев, форму отправки и поле этой формы у нас уже найдено, обработчик отправки .onsubmit
и по вводу .oninput
уже тоже есть. Как нам запретить отправку формы? Можно заблокировать кнопку «Отправить»!
Заблокировать ее можно с помощью свойства .disabled
которое принимает уже знакомые нам True и False. Всё остальное мы уже знаем и умеем, а значит пора все собрать в кучу!
Находим кнопку и счётчик, объявляем переменные и сразу мастерим условную конструкцию if {} else {}
используя полученное число символов:
let commList = document.querySelector('.list'); // блок комментариев let commForm = document.querySelector('.form'); // форма let commInput = document.querySelector('.input'); // поле формы let commCounter = document.querySelector('.counter'); // счётчик let subButton = document.querySelector('.submit'); // кнопка commInput.oninput = function () { charCounter.textContent = commentField.value.length; // обнавляем счётчик if (commInput.value.length > 142) { // если превышает 142 commForm.classList.add('warning'); subButton.disabled = true; // блокируем кнопку } else { commForm.classList.remove('warning'); // если не превышает subButton.disabled = false; } };
Осталась небольшая проблема — после корректной отправки комментария у нас не обнуляется счетчик. Это обнуление можно воткнуть в .onsubmit
присвоив контенту счетчика значение = 0.
Испытание
Очень прикольное испытание в этой части! Нужно реализовать работу клавиатуры на экране. Все сверстано, понятное дело, даны классы и пояснения что должно получится.
Испытание чисто на понимание коллекций и циклов, я представляю как тут можно намудрить, но у меня как-то сработали мои три извилины и я даже не подсматривал в уроки.
Часть 3: Прокрутка и операторы
Снова две задачки и два новых обработчика событий. Одна из них тривиальная — добавить кнопку «Наверх» при скролле вниз, вторая на первый взгляд сложная, по крайней мере я, намучившийся с WordPress и их таксономиями, сразу напрягся, но в нашем случае всё намного проще!
Кнопка «Наверх»
Задача не просто сделать кнопку «наверх», иначе можно было её сделать просто через якорь, а сделать так, чтобы она появлялась при прокрутке вниз на 200px и исчезала если такой прокрутки нет.
Нас сразу знакомят с обработчиком событий прокрутки .onscroll
— он срабатывает при малейшей прокрутки страницы, причем как по вертикали, так и по горизонтали, если это предусмотрено на страницу.
Отследить скролл можем, теперь нужно количественно его определить. Для этого используем свойство .pageYOffset
которое применяется к окну браузера window и полная запись выглядит вот так:
console.log(window.pageYOffset); // выведет число px верт. прокрутки
За горизонтальную прокрутку отвечает .pageXOffset
, но нам он сейчас не нужен, да и вообще он достаточно редко нужен, наверное. Хотя, я также думал про таблицы в HTML.
Хорошо, мы знаем как отследить скролл и его точное количество пикселей, мы уже можем построить условную конструкцию для появления кнопки. Но нам надо, чтобы она заработала — возвращала страницу наверх по нажатию на нее.
Для этого есть метод .scrollTo(X, Y)
— он «отправляет» область просмотра к указанным координатам, выравненным по левому верхнему углу. Тут будет проще показать картинку из урока:
window.scrollTo(100, 50);
Теперь у нас точно всё есть! Нам нужно найти кнопку и сделать два обработчика — один на скролл, что бы показать кнопку, второй на клик по этой кнопке. И не забыть скрыть её если скролл меньше 200 px. В итоге получается:
let upButton = document.querySelector('.up-button'); // кнопка window.onscroll = function () { // событие на скролл if (window.pageYOffset > 200) { // проверка прокрутки upButton.classList.add('shown'); } else { upButton.classList.remove('shown'); } }; upButton.onclick = function () { window.scrollTo(0, 0); // отправляем к верхнему левому углу };
Пока что это самое простое задание из блока, хотя, это кажется после сложных комментариев. Но дальше задачка еще сложнее.
Фильтр контента
Если точнее — нужно сделать фильтр публикаций в ленте по категориям. Такая задача может быть реализована очень по разному — дофига факторов к этому.
В нашем случае мы, понятное дело, реализуем через JS. Будем использовать data-атрибут у блоков новостей, отвечающий за их категорию — у каждого блока в вёрстке заранее прописан этот атрибут со значением определенной категории. Таким образом мы сможем потенциально их различить, ведь как обращаться к data-атрибутам мы уже знаем.
Сама фильтрация будет через выпадающее меню <select>, где пункты соответствуют конкретной категории и отдельно пункт «Все новости», который нам тоже надо реализовать.
Итак, у нас складывается картина — есть какое-то количество новостей и фильтрующий элемент. Для начала найдем их — нам нужны все новости, поэтому находим все селекторы на странице:
let articles = document.querySelectorAll('.news-block'); // новости let filter = document.querySelector('.filter'); // меню фильтра
Дальше как нам их связать? С помощью нового для нас обработчика событий .onchange
, который срабатывает каждый раз, когда значение указанного элемента изменяется.
В нашем случае изменяется выбранная опция выпадающего меню — к нему мы и будем обращаться! Итак, дальше нам нужно, чтобы при выборе пункта меню, проверялось соответствие выбранной категории к указанной категории новости в data-атрибуте и если они совпадают — показать новость, а остальные скрыть.
Про свойство .dataset
мы знаем, условную конструкцию if () {} else {}
тоже уже несколько раз использовали. Кажется вроде всё есть, но дойдя до условия окажется, что есть нюансы.
В JS есть различные операторы соответствия — «равно» или «не равно» может быть строгим и нестрогим, а еще просто символ «=» это не «равно».
num1 === num2 // строгое равенство (три равно подряд) num1 !== num2 // строгое неравенство (! и два равно) num1 == num2 // нестрогое равенство (два равно) num1 != num2 // нестрогое неравенство (! и равно) // Ох уж это форматирование операторов здесь. Вот нахрена?
В тренажере не особо вдаются в подробности различия строгих и нестрогих операторов, но для нас сейчас важны именно строгие. С их помощью мы сможем написать условную конструкцию, которая будет проверять соответствие атрибута у новости с текущим значением выпадающего меню.
filter.onchange = function () { // меняем пункт меню for (let article of articles) { if (article.dataset.category !== filter.value) { // проверяет атрибут article.classList.add('hidden'); // если его нет - скрывает } else { article.classList.remove('hidden'); // иначе показывает } } };
Отлично, всё работает кроме пункта «Все новости» — при его выборе новости пропадают, а должно быть наоборот. Действительно, ведь этот пункт попадает под условие скрытия. Нужно дополнить условие и в этом нам поможет еще один оператор Логическое И &&
(два амперсанда).
Используя его, мы дополняем условие еще одним параметром. Я немного перенесу строки, чтобы уместилось и было наглядно:
filter.onchange = function () { // меняем пункт меню for (let article of articles) { if ( article.dataset.category !== filter.value // первое условие && // Логическое И filter.value !== 'all' // Второе условие ) { article.classList.add('hidden'); } else { article.classList.remove('hidden'); } } };
Готово! Таким образом, условие гласит — «Скрыть если не соответствует выбранной категории И если не выбрано 'all'» — то, что нам нужно.
Испытание
Задача в испытании — настроить цензуру! Форма отзыва с радио-кнопками, некоторые пункты положительного характера, некоторые отрицательного. Они так и помечены 'good' и 'bad' в специальном data-атрибуте.
Пришлось немножко потупить в монитор. Именно потупить, несколько раз прочитать задание. Основной «ловушкой» здесь является то, что в течение прохождения тренажёра у нас цикл внутри обработчика, а здесь надо сделать наоборот.
Часть 4: Динамические стили элементов
В заключительной части тоже две задачи, хотя, во второй две как бы отдельные подзадачи. Но ничего — справимся! Будем с помощью JS менять значения свойств из CSS и показывать всем свой пароль.
Настройки стиля
У статей из заданий появились настройки стилей — ползунок с размером текста два выпадающих меню с цветом текста и фона, а наша задача с помощью JS реализовать их работоспособность.
С дроп-меню мы уже знакомы, а ползунок еще не встречали, причем, даже в блоке про HTML. Тут нас с ним легонечко знакомят — это <input> типа type="range"
, который так же принимает атрибуты минимального и максимального значения min=""
и max=""
, а еще шаг step=""
.
В нашем случае диапазон настройки размера текста от 8px до 48px с шагом 1px. Не будем на нём заострять внимание, я уверен, еще на заостряемся в следующих блоках.
На сцену выходит свойство .style
, которое обращается к указанному CSS свойству элемента. В CSS, правда, очень много свойств записано через дефис и здесь, как и в случае data-атрибутов, записывать нужно в «верблюжьем» стиле. То есть обращение к background-color будет выглядеть так:
someElement.style.backgroundColor
Итак, для начала определим все элементы, нам нужно найти саму область статьи, оба дроп-меню, ползунок и еще счетчик пикселей над ним:
let longread = document.querySelector('.longread'); // статья let colorSetting = document.querySelector('.color-setting'); // цвет текста let bgSetting = document.querySelector('.bg-setting'); // цвет фона let sizeSetting = document.querySelector('.size-setting'); // ползунок let pixels = document.querySelector('.pixels'); // счетчик ползунка
Дальше просто — у всех настроек есть value, хватаем его, пихаем в обработчик событий .onchange
и все будет работать! Да, но опять есть нюанс.
Если мы применим .onchange
для ползунка, то окончательно применятся стиль, то бишь выполняться скрипт в обработчике, будет только после отпускания левой кнопки мыши. Соответственно, изменение размера текста будет не достаточно наглядным.
С ползунком лучше подойдет обработчик событий .oninput
который срабатывает при каждом изменении значения, то бишь каждый шаг step=""
. Таким образом размер текста будет изменятся более плавно.
colorSetting.onchange = function () { // цвет текста longread.style.color = colorSetting.value; }; bgSetting.onchange = function () { // цвет фона longread.style.backgroundColor = bgSetting.value; }; sizeSetting.oninput = function () { // размер текста pixels.textContent = sizeSetting.value; // счетчик longread.style.fontSize = sizeSetting.value + 'px'; // не забыть про px! };
Задача относительно простая, особенно учитывая пройденные выше этапы. Но здесь вся часть больше на нюансы и важные свойства, чем на новые функции, что тоже крайне важно.
Покажи пароль, а если найду?
Следующая задача содержит в себе две подзадачи, обе связаны с полем ввода пароля в форме регистрации. Из прошлого блока мы знаем про различные типа полей, в том числе поле с паролем type="password"
, который по умолчанию скрывает вводимую информацию, заменяя символы звёздочками.
Но иногда пароль не qwerty123 и нужно проверить правильность его написания, особенно при регистрации на сайте. Для этого нам нужна кнопка или, в нашем случае, переключатель, показывающий что же мы там ввели.
Для этой задачи в JS есть одноименные с HTML атрибуты и свойства — это свойство .type
, которые, очевидно, обращается к одноименному атрибуту элемента. А так же, так как для скрипта на понадобится условная проверка переключателя, в JS есть свойство .checked
, который проверяет наличие этого атрибута у элемента, то есть проверяет наличие галочки у чекбокса.
Итак компоненты у нас есть, надо свести их в одну конструкцию. Находим само поле и переключатель, затем проверяем состояние переключателя и в зависимости от результата меняем тип поля. Получается:
let password = document.querySelector('.password'); // поле пароля let showPassword = document.querySelector('.show-password'); // чекбокс showPassword.onchange = function () { if (showPassword.checked) { // вкл. показать пароль password.type = 'text'; // меняем на текстовое поле } else { // выкл. показ пароля password.type = 'password'; } };
Как и в прошлом задании выше, здесь мы разобрались с простыми, но важными свойствами, которые, я уверен, крайне часто применяются на практике.
Следом нам надо реализовать индикатор длинны пароля. Но не просто счётчик, как мы делали в комментариях, а визуально полоску индикатора, которая будет расти и менять цвет в зависимости от длинны пароля. Такое много где встречается, вот сейчас и мы такое сделаем.
Подумаем что нам для этого надо. Узнать длину пароля с помощью .value.length
мы сможем. Перекрасить полоску с помощью .style
— тоже разберёмся. Мы не знаем как менять размер полоски, но дедуктивным методом можно предположить, что CSS свойство width мы тоже можем вызвать через свойство .style
— проверим!
Что еще нужно? Полоска имеет три статуса — красная, когда пароль совсем короткий и имеет меньше шести символов, желтая, когда пароль подходит по длине, но всё еще короткий и имеет от шести до девяти символом и, наконец, зелёная, когда пароль достаточно длинный и имеет десять и более символов.
То есть условия три, а мы до этого разбирали только два. Но всё решается достаточно просто — уловная конструкция может быть расширена с помощью промежуточного условия else if () {}
и таких условий может быть сколько требует конкретная задача.
Про уловные и математические операторы — большем, меньше, умножить и так далее, я отдельно писать не буду, так как они работают очевидно. Давайте соберем все в кучу, выше мы уже нашли поле пароля и чекбокс, осталось найти саму полоску и написать для нее обработчик событий с условной конструкцией:
let securityBar = document.querySelector('.security-bar'); password.oninput = function () { // длину пароля записываем в переменную, для удобства let passLength = password.value.length; // ширина полоски рассчитывается в % ширины контейнера securityBar.style.width = passLength * 10 + '%'; // 1 символ = 10% if (passLength <= 5) { // < и = (опять форматирование) securityBar.style.backgroundColor = 'red'; } else if (passLength > 5 && passLength < 10) { // от 6 до 9 включ. securityBar.style.backgroundColor = 'gold'; } else { // 10 и больше securityBar.style.backgroundColor = 'green'; } };
В тренажёрах отдельными уроками выведено то, что я тут в комментарии написал — про запись переменной в обработчике и расчёт ширины полоски. Я не стал лишний раз заливать воды в озеро, так как по комментариям и так понятно.
В итоге всё работает — мы великолепны! Общий скрипт задачи вместе с показом пароля достаточно длинный, я не буду его копировать — это компиляция двух блоков выше.
Испытание
Очень крутое испытание — пишем свой аналог Photoshop для бедных! Есть поле в котором есть «пиксели» — это квадратные <div>'ы определённого размера, есть дроп-меню с цветами и «ластик», который на самом деле просто белый цвет.
Задачка тоже из разряда «потупить 10 минут», то есть сначала все в голове сложить, а потом уже писать код. Я сначала еще по выпендривался с записью переменной в обработчике, но что-то у меня не сработало. Скорее всего, её надо было выводить из обработчика под for. Главное решил.
Вот мы и закончили "Знакомство с JavaScript". Надо сказать было очень интересно, я прям в восторге от этой части, намного больше понравилась чем "Знакомство с HTML и CSS". Возможно, это из-за того, что я её затянул.
Вообще, я теперь понимаю, почему иногда в разговоре со знакомыми веб-разработчиками я видел очень разную реакцию на HTML/CSS и на JS. JavaScript элементарно интереснее, на мой взгляд. Но я все еще в начале пути, будем смотреть, может есть подводные камни.
Спасибо большое тем героям, что дочитали эту колбасень текста, получилось реально дофига, но я уже начал привыкать столько строчить. Надо было идти на журфак, а не на эти ваши физики. Шучу.
Ссылки на остальные статьи по HTML Academy:
Знакомство с Веб-разработкой
Знакомство с HTML и CSS
Знакомство с JavaScript <- Вы здесь
Знакомство с PHP
Таблицы и подробно о формах
Наследование, каскады и селекторы
Блочная модель, поток и сетка на float
Гибкие флексбоксы display: flex
Удобные сетки на гридах display: grid
Пропуск блока «Погружение»
Позиционирование и двумерные трансформации
Теневое искусство и линейные градиенты
CSS-фильтры и Кекстаграм
Мастерские
Продвинутые Мастерские
...
Остальные статьи можно посмотреть у меня на главной странице блога.
Также мои соц. сетки, которые я продолжаю вести:
Мой Twitter
Мой Telegram
Мой Паблик ВК
Заходите куда удобно вам и подписывайтесь! Еще раз спасибо за внимание!