Уроки, извлеченные из конкурса Javascript 30 Challenge

Если вы хотите освоить основы Javascript, вам необходимо пройти этот курс. Javascript 30 Challenge был создан Уэсом Босом, опытным дизайнером и разработчиком, и состоит из 30 задач, написанных на простом, ванильном Javascript, CSS и HTML — без препроцессоров или фреймворков. Мне не удалось выполнить задание в указанное время, но я все же многому научился в процессе. Ниже я расскажу о различных задачах, о том, как работают проекты, и о том, чему я научился в каждом из них.

Ударная установка —

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

Во-первых, давайте пройдемся по HTML. Оболочка div содержит девять div для ключей с элементом kbd, который представляет ввод пользователя, и элемент span с примечанием, относящимся к букве. Также есть девять звуковых элементов для каждой ноты. Девять внутренних элементов div и audio включают атрибут data-key, который равен коду ключа или значению ASCII различных букв.

Для CSS ничего особенного не происходит. Один добавленный эффект — это преобразование клавиш, которое увеличит размер и добавит желтую рамку вокруг блока. Эти атрибуты хранятся в классе «.playing», который будет присоединен к элементу при нажатии клавиши.

Теперь о том, где происходит вся магия — Javascript. Код довольно прост. Есть две функции, которые передают параметр «событие», запускаемый прослушивателем событий. Первый крепится к окну, а второй к клавишам.

Первая функция, «playSound», привязана к окну и запускается только при нажатии одной из клавиш. Эта функция включает в себя две переменные, «аудио» и «ключ», которые назначаются селекторам запросов, которые нацелены на атрибут keyCode или «ключ данных». Для упрощения кода в процессе таргетинга используются шаблонные строки, обозначенные обратными галочками. Вот как выглядят аудио и ключевые переменные:

const audio = document.querySelector(`audio[data-key=”${event.keyCode}”]`);
const key = document.querySelector(`.key[data-key=”${event.keyCode}”]`);

Событие равно нажатой клавише, которая генерирует определенный номер ASCII. Например, A в ASCII равно 65. При нажатии одной из вышеуказанных клавиш будет воспроизводиться соответствующая нота и будет добавлен класс «playing». Последние два компонента этой функции — это условный оператор, который останавливает выполнение функции, когда keyCode не распознан, и использование метода currentTime для аудиоэлемента, который мы установили равным t0 нулю, для воспроизведения аудио. снова, даже если он не закончен.

Вторая функция, «removeTransition», просто удаляет класс «.playing» из выбранного элемента в конце перехода.

Чтобы увидеть полный проект нажмите здесь.

И это все, что касается барабанной установки. Посмотрим, что нас ждет в следующем проекте.

Часы JS и CSS —

Часы используют объект «new Date()» для получения текущих часов, минут и секунд. С этими числами и небольшой геометрией, относящейся к кругам, вы можете определить расположение стрелок различных юнитов.

HTML для этого проекта очень прост. Первый div — это контейнерный div, внутри него находится div, содержащий циферблат. Внутри блока «циферблат» есть еще три блока для часов, минут и секундной стрелки.

CSS для этого проекта научил меня нескольким новым свойствам. Первым был display: flex, который прикреплялся к элементу body. Это свойство указывает, как элементы в этом контейнере будут увеличиваться или уменьшаться в соответствии с пространством. Таким образом, если размер экрана изменится или программист изменит размер корпуса, циферблат и размер заголовка должны измениться соответствующим образом.

Еще одним новым для меня свойством стала transition-timing-function, которая была присвоена классу рука. Это свойство дает нам больший контроль над переходом элемента, позволяя использовать различные значения ключевых слов (т. е. легкость, линейность, пошаговое начало и т. д.), значения функций (т. е. кубический-безье (0,1, 0,7, 1,0, 0,1) ), несколько функций синхронизации или глобальные значения (т. е. наследование, начальное или неустановленное).

Последние важные аспекты CSS для понимания этого проекта связаны с трансформацией рук. Руки нужно повернуть на 90 градусов, направить прямо вверх. Однако, если мы просто сделаем «transform: rotate(90deg)», то все стрелки будут вращаться в точке, равной половине их длины. Чтобы исправить это, мы используем «transform-origin» и устанавливаем его равным 100%. Это повернет стрелки так, чтобы начало координат было концом их длин или точкой, ближайшей к центру циферблата.

А теперь Javascript.

Во-первых, мы ориентируемся на секундную, минутную и часовую стрелки и устанавливаем их равными переменным. Затем мы создаем функцию setDate. Эта функция сначала устанавливает текущую дату в переменную с помощью конструктора «новая дата». Теперь, чтобы получить секунды, минуты и часы, мы используем методы объекта даты «getSeconds, getMinutes и getHours». Я включил этот процесс для секундной стрелки здесь:

const now = new Date();

постоянные секунды = now.getSeconds();

Я продолжу код для секунд, потому что этот процесс можно легко применить к минутам и часам. Когда у нас есть секунды текущей даты, мы делаем небольшую геометрию:

const secondDegrees = ((секунд/60) * 360) + 90;

secondHand.style.transform = `rotate(${secondsDegrees}deg)`

Первая переменная вычисляет степень, которой равна конкретная секунда внутри круга. 90 градусов, добавленные в конце, должны учитывать начальное преобразование 90 градусов, которое мы сделали, чтобы установить стрелки равными 12 в CSS. Затем мы обновляем градус и поворот стрелки, используя вторую строку кода. Этот процесс повторяется для минутной и часовой стрелок, за исключением часов, которые вы делите на 12 вместо 60. Чтобы перевести часы в текущее время и двигаться, наша последняя строка Javascript представляет собой функцию setInterval, содержащую 'setDate ' и интервал, равный 1000 миллисекунд.

Часы работают, однако вы заметите незначительный сбой, когда любая из стрелок достигает 12 — стрелка поворачивается против часовой стрелки и сбрасывается. Чтобы исправить это, я добавил условный оператор к каждой из стрелок, снимающих переход, когда он достигает 90 градусов. Для минутной стрелки код выглядит так:

if (minutesDegrees === 90) {

minuteHand.style.transition = ‘нет’;

} иначе {

minuteHand.style.transition = ‘’

}

Ну, это должно быть все для этого проекта. Если мое объяснение вам не подходит, посмотрите завершенный проект здесь.

Теперь давайте узнаем о некоторых переменных CSS.

Переменные CSS и JS —

Этот проект представляет новую функцию в CSS — переменные. Разработчик Mozilla определяет переменные CSS следующим образом:

…сущности, определенные авторами CSS, которые содержат определенные значения для повторного использования в документе. Они устанавливаются с использованием нотации пользовательских свойств (например, --main-color: black;) и доступны с помощью функции var() (например, color: var(--main-color);).

Давайте пройдемся по HTML. Во-первых, у нас есть заголовок с «JS», представляющий собой диапазон с классом «hl». После этого у нас есть наш div «controls» с метками и входными данными для интервалов, размытия и цвета. Для ввода интервалов и размытия мы должны добавить класс «размер данных». Этот класс будет помещен в объект набора данных, который находится в глобальном окне, и позже будет доступен с помощью некоторого Javascript. Наконец, у нас есть изображение кекса. На изображение будут влиять все три вышеупомянутые переменные, а на элемент span с классом «hl» будет влиять только цвет. Теперь давайте перейдем к CSS.

В CSS мы определяем наши переменные в корневом классе, который, по сути, нацелен на элемент самого высокого уровня в документе. Код для этого выглядит следующим образом:

:root {
— база: #FF5900;
— интервал: 10 пикселей;
— размытие: 10 пикселей;

Как только переменные определены в корневом классе и установлены базовые значения, мы присоединяем переменные к элементу изображения и классу «hl», что выглядит следующим образом:

img {
padding: var( — spacing);
background: var( — base);
filter: blur(var(— blur));
ширина: 25%;
высота: 25%;
радиус границы: 25%;
верхнее поле: 25 пикселей;
}
.hl {
цвет: var( — base);

Как только ваш стиль будет готов, мы можем обновить эти переменные с помощью некоторого Javascript.

Корректировки этих переменных используются через прослушиватели событий, прикрепленные к элементам ввода. В этом случае мы хотим, чтобы событие запускалось при изменении ввода или перемещении мыши при нацеливании на ввод. Если событие инициировано, прослушиватель вызовет функцию и передаст событие в качестве параметра.

Функция handleUpdate состоит всего из двух строк. Первая строка использует объект «набор данных» для определения единицы измерения — в данном случае единицей измерения являются пиксели. Во второй строке используется setProperty для documentElement вместе со строками шаблона для обозначения конкретного элемента и изменения значения переменной CSS. Завершенная функция в конечном итоге будет выглядеть так:

function handleUpdate() {
const suffix = this.dataset.sizing || '';
document.documentElement.style.setProperty(` — ${this.name}`, this.value + суффикс)

Это позволяет нам изменить размер границы, размытие изображения или цвет рамки и элемента span.

Чтобы увидеть завершенный проект нажмите здесь.

Что дальше?

Массивное кардио, день 1 —

Cardio Day 1 — это скорее урок функций высшего порядка, чем проект. Бос рассказывает о методах фильтрации, сопоставления, сортировки и сокращения, а также о том, как использовать каждый из них с объектом данных.

Наиболее интересным упражнением является сортировка изобретателей в алфавитном порядке по фамилии. Мы использовали метод sort для массива, а затем переформатировали каждую строку в массив [lastName, firstName]. После этого мы возвращали массивы с помощью тернарного оператора, который сравнивает алфавитное значение каждой строки. Вот готовый продукт:

const name = people.sort((a, b) =› {
const [aLast, aFirst] = a.split(', ');
const [bLast, bFirst] = b .split(', ');
вернуть aLast › bLast ? 1 : -1;
});

Чтобы посмотреть решения остальных проблем нажмите здесь.

Теперь к следующему.

Гибкие панели —

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

Для HTML есть блок-контейнер, а внутри него шесть блоков-панелей с собственным классом. Внутри каждой отдельной панели есть три тега абзаца — один будет оставаться видимым все время, а два других будут скользить при нажатии на панель.

CSS для этого проекта представил несколько новых концепций.

Первое новое свойство, с которым я столкнулся, было box-sizing: border-box. Свойство box-sizing используется, чтобы сообщить браузеру, что должны включать в себя свойства размера. Для рамки ширина и высота будут включать размер границы элемента и любые отступы, но исключают любые поля. Значение по умолчанию, content-box, просто измеряет ширину и высоту элемента и исключает границы, отступы и поля.

Следующее, с чем я столкнулся, с чем я не был знаком, был этот код:

*, ​​*:before, *:after {
box-sizing: inherit;

После небольшого исследования я обнаружил, что «*» означает все элементы на странице. «*:before» означает все элементы, которые идут перед элементом; и аналогичным образом ‘*:after’ нацелен на все элементы, которые идут после элемента. Значение «наследовать» просто относится к «рамке», которую мы присвоили свойству box-sizing элемента HTML. Далее мы реализуем свойства flex.

Чтобы это работало, мы помещаем свойство «display: flex» в родительский элемент элементов, которые мы хотим иметь гибкими характеристиками — в данном случае панели div. Каждая панель будет иметь свойство «flex» со значением, равным 1, что означает, что каждая панель будет равномерно распределять между собой дополнительное пространство в div-контейнере. Чтобы панели выровнялись по вертикали, мы добавляем свойство «flex-direction: column». панелей. Когда выбрана панель, переход включает в себя изменение размера шрифта тегов абзаца, размера панели (flex или flex-grow) и непрозрачности фона.

Другая часть этого CSS, с которой я не был знаком, заключалась в следующем:

.panel › * {

}

Этот класс предназначен для каждой отдельной панели. Знак «›» указывает на дочерние элементы, которые находятся в этом элементе, и еще раз «*» означает все элементы. Итак, чтобы собрать все это вместе, вышеперечисленное означает все элементы, которые находятся внутри каждой отдельной панели. Свойства, которые мы включаем в этот класс, сосредоточены на центрировании всех элементов.

Следующий код используется для того, чтобы теги абзаца скользили по странице:

.panel › *:first-child {
transform: translateY(-100%)
}
.panel.open-active › *:first-child {
transform: translateY(0)
}
.panel › *:last-child {
transform: translateY(100%)
}
.panel.open-active › *:last-child {
transform: translateY(0)
}

И снова «*» появляется для обозначения всех элементов, которые являются первыми дочерними элементами в панели (первый тег абзаца) и последними дочерними элементами в панели (третий тег абзаца). После нацеливания к панели прикрепляется класс «open-active», а теги абзаца (first- и last-child) вставляются.

Последняя часть CSS, которую я рассмотрю, — это класс «open», который увеличит размер шрифта до 20 пикселей, непрозрачность до 1 и значение гибкости до 5. Когда класс прикреплен к панели и flex становится равным 5, целевой элемент будет занимать в 5 раз больше места по сравнению с другими элементами, находящимися в контейнере.

Большая часть этого проекта выполнена с помощью CSS, но требуется немного Javascript. Я буду краток. Нам нужно добавить прослушиватели событий на каждую панель, чтобы определить, когда она выбрана, и когда переходы заканчиваются. Javascript работает таким образом, что при нажатии на панель включается класс «открыть», непрозрачность становится равной 1, а размер панели увеличивается. В конце перехода теги абзаца вставятся.

Вот завершенный проект.

Вводите вперед —

В этом проекте используется Javascript для вызова API и регулярные выражения для сопоставления информации в объекте данных. Когда мы сопоставляем значение, которое искал пользователь, мы выводим результаты в хорошо продуманный выпадающий контейнер.

HTML состоит из элемента формы, который содержит ввод текста и неупорядоченный список для отображения результатов.

В CSS нет ничего нового, но я хотел бы проверить, как Бос использует преобразование для создания эффекта сложенной бумаги.

Основная часть этого проекта находится в Javascript.

Во-первых, мы определяем переменные для источника данных и пустой массив для хранения определенных частей данных. Вместо jQuery для доступа к API мы используем выборку. Выборка возвращает объект обещания, который представляет возможное завершение (или сбой) асинхронной операции и ее результирующее значение. Мы затем преобразуем блок данных в читаемый формат JSON и затем помещаем результаты в пустой массив.

Затем мы нацеливаем ввод поиска для фильтрации наших результатов и элемент неупорядоченного списка для отображения результатов. Слушатели событий, которые мы добавляем к входным данным поиска, — это «change» и «keyup», которые запускают функцию «displayMatches» при срабатывании. Первая строка этой функции присваивает результаты функции findMatches переменной.

Функция findMatches принимает два параметра. Первое — это значение, которое ищет пользователь, а второе — массив городов. Он фильтрует массив, используя функцию высшего порядка, для каждого города или штата, которые соответствуют значениям, введенным пользователем. Если это объяснение вам не подходит, я говорю о следующем коде:

function findMatches(wordToMatch, city) {
return city.filter(place =› {
const regex = new RegExp(wordToMatch, 'gi');
return place.city. match(regex) || place.state.match(regex);
});
}

Теперь возвращаясь к функции displayMatches, мы берем наши результаты или массив совпадающих значений и сопоставляем их, чтобы выделить значения, равные введенным пользователем. Для этого мы начнем с создания еще одного регулярного выражения для пользовательского ввода. Затем мы создаем переменные для названий городов и штатов, которые соответствуют регулярному выражению, и заменяем совпадающее значение элементом span с цветным фоном. После выделения пользовательского ввода мы возвращаем следующий HTML-код, используя обратные кавычки:

‹li›
‹span class=’name’› ${cityName}, ${stateName} ‹/span›
‹/li›

Весь этот процесс объединяется в строку и устанавливается равной переменной с именем html. Элемент неупорядоченного списка теперь будет содержать элемент span, заполненный городом и штатом, а ввод пользователя будет выделен.

Вот мой завершенный проект на GitHub.

Массивное кардио, день 2 —

Давайте узнаем больше о манипулировании данными и функциях высшего порядка! Наборы данных, с которыми мы работаем в этих упражнениях, изображены выше. Бос рассказывает нам о методах some, every, find и findIndex.

Большинство из них говорят сами за себя. Some возвращает true, если условное выражение истинно хотя бы для одного значения. «Каждый» возвращает истину только в том случае, если условие истинно для всех значений. «Найти» возвращает искомое значение, а «findIndex» возвращает индекс этого значения.

В последнем упражнении мы находим индекс определенного значения, а затем Бос показывает нам два способа удалить это значение из массива. Первый способ использует сплайсинг, показанный здесь:

array.splice(index, 1);

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

const newComments = […comments.slice(0, index), …comments.slice(index+1)]

Надеюсь, вы чему-то научились. Вот остальные упражнения.

Развлечение с HTML5 Canvas —

В этом проекте используется новый элемент HTML5, Canvas. Бос показывает нам, как его настроить и реализовать некоторые двумерные функции с помощью Javascript.

Настроить холст в HTML очень просто — используйте элемент «холст» и укажите желаемые размеры (ширину и высоту).

Для холста не нужен CSS, поэтому давайте перейдем к Javascript.

Первое, что мы делаем, это используем «querySelector» для выбора холста и устанавливаем его равным переменной «холст». Затем мы получаем контекст холста, который в данном случае является двухмерным. Итак, код должен выглядеть так:

const canvas = document.querySelector(‘.canvas’);
const ctx = canvas.getContext(‘2d’);

Далее мы рассмотрим некоторые методы, которые мы можем прикрепить к переменной «ctx». Первый — «strokeStyle», это просто цвет обводки. Два других метода — «lineJoin» и «lineCap», оба имеют значение «round». Первый метод скругляет границу места пересечения двух линий, а второй скругляет начальную точку линии.

Теперь нам нужно прикрепить прослушиватели событий к холсту и определить переменную флага, чтобы различать, когда пользователь рисует. Также нам понадобятся две переменные для отслеживания положения мыши на холсте (lastX = 0, lastY = 0).

Первые два прослушивателя событий сработают, когда мы не хотим запускать функцию «рисования» — «mouseup» и «mouseout» — и вместо этого установим для переменной флага значение false.

Слушатель события «mousedown» установит переменную переменной флага равной true и использует событие, переданное в качестве параметра, для записи положения мыши в массив:

[последнееX, последнееY] = [событие.смещениеX, событие.смещениеY];

Наш последний прослушиватель событий, mousemove, запустит функцию draw, которая также передает инициированное событие в качестве параметра.

Функция «рисование» включает в себя четыре метода, необходимых для любого двумерного проекта, связанного с холстом. Во-первых, нам нужно условие, которое использует переменную флага и завершает функцию, если переменная ложна. Если пользователь рисует, мы присоединяем метод «beginPath» к переменной «ctx», чтобы начать путь линии или сбросить предыдущий штрих. Затем мы использовали метод «moveTo» и передали в качестве параметров значения lastX и lastY, найденные при срабатывании события «mousedown». Как только мы установили начальную точку линии, мы используем метод «lineTo», чтобы закончить линию в новом местоположении мыши. Новое положение мыши определяется с помощью инициированного события и методов «offsetX» и «offsetY». После этих трех методов необходимо определить местоположение и длину линии, а последний метод, «обводка», заполнит линию цветом. Чтобы перезапустить процесс, мы используем событие с «offsetX» и «offsetY», чтобы переназначить переменные «lastX» и «lastY».

Весь процесс выглядит так:

ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(event.offsetX, event.offsetY)
ctx.stroke();
[lastX, lastY] = [event.offsetX, event.offsetY];

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

14 хитростей с инструментами разработчика, которые необходимо знать —

В этом разделе рассматриваются 14 различных консольных инструментов, которые важно знать разработчику. Ниже приведен список этих инструментов:

  • Обычный: Console.log() — регистрирует любой тип данных, являющийся результатом функции.
  • Интерполировано: Console.log('Привет, я строка %s!, "какашка") — где "%s" будет заменено вторым значением. Это то же самое, что написать Console.log(`Привет, я ${var}`).
  • Styled: Console.log('%c У меня отличный текст!', 'font-size: 30px; background-color: red') — '%c' дает вам возможность стилизовать текст, который регистрируется в консоль.
  • Предупреждение: Console.warn(‘Oh Noo!’) — это скажет вам, где было вызвано предупреждение, и даст вам отслеживаемый стек, чтобы сказать вам, где было вызвано это предупреждение.
  • Error: Console.error(‘Error!’) — это скажет вам, где была вызвана ошибка, и даст вам отслеживаемый стек, чтобы сказать вам, где была вызвана эта ошибка.
  • Console.info(‘Забавный факт!’) — Info запишет строку в консоль вместе со значком информации.
  • Console.assert(1==2, ‘Неправильно!’) — этот инструмент проверит правильность условного выражения и, если ложь, зарегистрирует второй параметр — в данном случае «Неправильно!»
  • Console.clear() — инструмент очистки очистит вашу консоль от любой предыдущей работы.
  • Console.dir(элемент HTML) — Console.log(p) выведет на вашу консоль элемент абзаца, но если вы хотите узнать все доступные свойства и методы для этого элемента, который вы используете, Console.dir(p) и его даст вам вышеупомянутое в раскрывающемся списке.
  • Console.group()/Console.groupCollapse() /Console.groupEnd() — Параметр, переданный через ‘group’ или ‘groupCollapse’, будет заголовком для раскрывающегося списка всего, что регистрируется на консоли. Чтобы закончить список, относящийся к этой теме, вы передаете тот же параметр в «groupEnd».
  • Console.count() — инструмент подсчета регистрирует, сколько раз параметр был зарегистрирован в консоли. Таким образом, если бы было два Console.count('Steve'), консоль записала бы «Steve: 2».
  • Console.time()/Console.timeEnd() — вы передаете имя операции в качестве параметра, запускаете функцию или процесс, для которого хотите задать время, после чего следует console.timeEnd(), и инструмент записывает время ее выполнения. взялся за запуск этого процесса.
  • Console.table — инструмент берет массив объектов и, предполагая, что все они имеют одинаковые свойства, записывает их в таблицу.

Удерживайте клавишу Shift, чтобы установить несколько флажков —

В этом проекте мы изучаем код для проверки нескольких ящиков при нажатой клавише Shift — функция, которую вы используете при перемещении нескольких писем в папку со спамом.

HTML включает в себя блок-контейнер для всех флажков, а также ввод и метку флажка.

Что-то новое для меня в CSS было таким способом нацеливания на элемент ввода:

input:checked + label {
text-decoration: line-through;
color: red;

Этот класс активен только тогда, когда вход проверен. Если это так, то текст метки меняет цвет на красный и проходит через него.

В Javascript мы устанавливаем флажки и добавляем прослушиватель событий к каждому из них, который запускает функцию «handleCheck». Вне функции мы определяем переменную lastChecked, которая будет установлена ​​равной второму полю, которое мы проверяем. Внутри функции у нас есть флаговая переменная «inBetween», которая будет установлена ​​равной true, когда будет определен наш диапазон флажков.

Это происходит только в том случае, если нажата клавиша Shift (event.shiftKey) и установлен второй флажок (this.checked). Если эти две вещи верны, то мы сопоставляем флажки и определяем, был ли щелкнутый элемент флажком или присутствует флажок «lastChecked». Если хотя бы одно из этих условий верно, то мы устанавливаем для переменной флага значение true или ‘!inBetween’, что упрощает переключение между значениями. Чтобы завершить процесс, если «inBetween» имеет значение true, все флажки между первым и вторым выбранными будут отмечены. Весь этот процесс показан в коде ниже:

if (event.shiftKey && this.checked) {
checkboxes.forEach(checkbox =› {
if (checkbox === this || checkbox === lastChecked)
inBetween = !inBetween;
if (inBetween)
checkbox.checked = true;
});

Чтобы увидеть весь код этого проекта, нажмите здесь.

Пользовательский видеопроигрыватель HTML5 —

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

HTML включает в себя div для проигрывателя, который будет содержать элемент видео, и div для инструментов управления. Внутри div, которым управляет игрок, у нас есть div внутри div. Внешний элемент - это индикатор выполнения, а внутренний - для заполнения прогресса, в разделе управления проигрывателем есть кнопка воспроизведения, два ввода диапазона и значки быстрой перемотки вперед и пропуска вперед.

CSS требует дополнительной работы, так как определенные классы должны указывать, какой браузер используется — для этого проекта я использовал только Chrome и Firefox. Это относится в особенности к диапазонным входам. Код ниже изменяет CSS только для значка слайдера на входных дорожках:

input[type=range]::-webkit-slider-thumb { /*CHROME*/
высота: 12 пикселей;
ширина: 17 пикселей;
радиус границы: 50 пикселей;< br /> фон: #ffc600;
курсор: указатель;
-webkit-appearance: нет;

input[type=range]::-moz-range-thumb { /*FIREFOX*/
высота: 12 пикселей;
ширина: 17 пикселей;
радиус границы: 50 пикселей;< br /> фон: #ffc600;
курсор: указатель;

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

Кроме того, мы хотим, чтобы наши элементы управления были видны только при наведении курсора на игрока. Это легко сделать, добавив свойства преобразования в элемент управления проигрывателя и прослушиватель «наведения».

Что касается Javascript, я просто расскажу о функциях. Целевые элементы и добавленные к ним прослушиватели событий более или менее говорят сами за себя.

Первые две функции — togglePlay и updateButton — относятся к воспроизведению и приостановке видео. В функции «togglePlay» мы назначаем тернарный оператор переменной, которая использует свойство «пауза», определяющее, вызывается ли в данный момент метод «воспроизведение» или «пауза». «UpdateButton» использует ту же логику, чтобы определить, какой значок, «►» или «❚ ❚», должен быть виден в разделе инструментов управления.

Далее я расскажу о функции «пропустить». Функция пропуска использует «пропуск данных», определенный для двух кнопок в HTML. Пропуск имеет положительное значение, а обратный путь имеет отрицательное значение. Функция использует «это», чтобы определить, на какой из них вы нацелились, и добавляет это значение к текущему времени видео. Однако для того, чтобы это работало, вы должны преобразовать строку в число либо с помощью «parseFloat», либо с помощью символа добавления «+» перед строкой: «this.dataset.skip».

Далее следует функция handleRangeUpdate, которая обрабатывает любые изменения, которые вы вносите во входные данные, касающиеся звука и скорости видео. Используя «this», мы можем определить, на какой из вышеупомянутых входных данных мы нацелились, и прикрепив «.value» к новому значению этого параметра. Вся функция состоит из одной строки — «video[this.name] = this.value».

Предпоследняя функция — это функция «handleProgress», которая корректирует заполненный прогрессом div в соответствии с процентом завершенного видео. Для этого мы вычисляем процент, равный текущему времени видео, деленному на продолжительность видео, умноженному на 100. Затем мы используем эту строку кода — 'progressBar.style.flexBasis = `${percent}%`' — для обновления ширина заполненного прогрессом div.

Наша последняя функция — это функция «прокрутки», которая используется для щелчка и перетаскивания индикатора выполнения в нужную точку фильма. Это делается с помощью инициированного «события» и «смещения X», чтобы определить, где на панели мы щелкнули. Получив это значение, мы делим его на общую ширину полосы. Затем свяжите соотношение с видео, умножив его на продолжительность видео. Мы присваиваем полученное значение переменной, а затем устанавливаем текущее время видео этой переменной, чтобы все это работало.

Это мое объяснение того, что происходит с пользовательским видеоплеером HTML5. Делается очень много, и я добавил еще несколько фич к тому, что сделал Бос, так что предлагаю вам ознакомиться с кодом на GitHub.

Обнаружение последовательности клавиш (KONAMI CODE) —

В этом проекте используется определение последовательности клавиш, чтобы определить, набрали ли вы конкретное слово или фразу. Если да, то запустится Cornify.js — программа, которая выводит на экран единорогов и радуги.

В HTML и CSS нет ничего нового, поэтому давайте просто сосредоточимся на Javascript.

Сначала создайте две пустые переменные — одна представляет собой пустой массив, а другая равна слову или фразе, которую вы хотите использовать в качестве кода KONAMI. Затем прикрепите к окну прослушиватель событий с триггером «keyup», а событие будет передаваться через анонимную функцию. Символы, нажатые пользователем, должны быть помещены в пустой массив. Используйте код — «pressed.splice(-code.length — 1, press.length — code.length)» — чтобы сравнить длину секретного кода с буквами, которые набрал пользователь. Соедините последние набранные буквы в строку, равную длине секретного кода, если массив содержит фразу, затем запустите функцию Cornify.

Программа Key Sequence Detection была довольно простым проектом. Чтобы проверить код нажмите здесь.

Прокрутка при прокрутке —

Этот проект фокусируется на эффекте скольжения, который создает впечатление, будто изображение скользит по экрану, когда пользователь прокручивает страницу вниз. Эффект использует свойства окна вместе с прослушивателем событий «прокрутки».

В HTML нет ничего нового, только несколько тегов абзаца и несколько изображений.

Все изображения на этой странице будут сдвинуты влево или вправо. Если изображение перемещается влево, то позиция X изображения будет смещена влево (translateX -30%). Если изображение перемещается вправо, то позиция X изображения будет перемещена вправо (translateX 30%). Класс «слайд-ин» определяет, какие изображения получат эффект. Он устанавливает непрозрачность равной нулю и добавляет полусекундный переход. Когда «активный» класс добавляется к изображениям, предназначенным для вставки, непрозрачность возвращается к единице, а положение X — к исходному значению (перевести X на 0%). Теперь нам нужно определить, когда к изображению присоединен «активный» класс.

В Javascript мы сначала прикрепили прослушиватель событий прокрутки к окну, которое запускает функцию, называемую checkSlide. У прослушивателя событий прокрутки есть проблема — он запускает слишком много событий. Чтобы решить эту проблему, нам нужно включить функцию debounce, которая добавит временной интервал к прослушивателю событий, который ограничивает количество запусков checkSlide до одного раза каждую n-ю секунду.

Затем мы определяем функцию «checkSlide», сначала перебирая все целевые изображения. Затем мы вычисляем ряд значений, чтобы определить, когда изображение должно скользить. Эти переменные перечислены ниже — я расскажу о каждой из них и о том, как они рассчитываются:

const slideInAt = (window.scrollY + window.innerHeight) — sliderImage.height / 2;
const imageBottom = sliderImage.offsetTop + sliderImage.height;
const isHalfShown = slideInAt › sliderImage.offsetTop;
const isNotScrolledPast = window.scrollY ‹ imageBottom;

В первой переменной «window.scrollY» сообщает нам, как далеко мы прокрутили вниз от верхней части нашего браузера. Чтобы получить нижнюю часть экрана, мы добавляем «window.innerHeight». Поскольку мы хотим, чтобы изображение скользило, когда мы прокручиваем страницу до половины его высоты, мы вычитаем -(sliderImage.height/2).

Когда мы прокручиваем изображение, мы хотим, чтобы оно исчезало. Поэтому, когда мы прокручиваем вверх, мы хотим знать, где на экране находится нижняя часть изображения. Чтобы найти его, мы используем «sliderImage.offsetTop», который сообщает, как далеко верхняя часть изображения находится от верхней части окна. Затем мы добавляем «sliderImage.height», чтобы добраться до нижней части изображения.

Последние две переменные устанавливаются равными логическим значениям. Переменная «isHalfShown» указывает, когда изображение должно скользить — когда значение slideInAt больше, чем верхняя часть изображения на странице. Наша последняя переменная isNotScrolledPast проверяет, не прокрутили ли мы изображение, потому что, когда пользователь достигает этой точки, изображение должно исчезать. Последняя часть функции «checkSlide» — это условный оператор, который добавляет «активный» класс, когда эти две переменные истинны, и удаляет класс, когда обе они ложны.

И вот вам эффект слайд-ин. Чтобы ознакомиться со всем кодом, особенно с функцией debounce в простом javascript, нажмите здесь.

Ссылки на JavaScript и копирование —

Этот раздел представляет собой урок о разнице между ссылкой и копией. Важно знать разницу между ними, поскольку это обычно является причиной ошибок и ошибок.

Бос использует первое упражнение, чтобы продемонстрировать ссылку на переменную. Есть две переменные. Первая переменная равна числу. Вторая переменная устанавливается равной первой. Затем он переназначает первой переменной новое значение. Когда он вызывает две переменные, первая равна новому значению, а вторая по-прежнему ссылается на старое значение первой переменной. Та же логика применима и к строкам, но как насчет массивов?

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

  1. массив.срез()
  2. [].concat(массив)
  3. […множество]
  4. Массив.от(массив)

Как только копия сделана, вы устанавливаете ее равной второй переменной. Любые изменения, внесенные в скопированный массив, не повлияют на исходный массив.

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

  1. Object.assign({}, obj, {свойства: вы хотите изменить})
  2. Объект.создать(объект)
  3. {…obj} (скоро может появиться для Javascript)

Важно отметить, что когда вы копируете объект, он копирует только один слой вглубь — это означает, что если одно из значений свойства является объектом, то эти защитные свойства оригинала не будут перенесены на этот внутренний объект. Таким образом, любые изменения, внесенные вами в эту копию объекта внутри более крупного объекта, повлияют на оригинал. Хотя в редких случаях вам нужно выполнить глубокое клонирование объекта, некоторые библиотеки предлагают функцию глубокого клонирования, или, если вы предпочитаете использовать простой Javascript, есть глубокое клонирование бедняка — JSON.parse (JSON.stringify(объект)).

Надеюсь, вы чему-то научились. Вы можете найти мою работу к уроку здесь.

Локальное хранилище и делегирование событий —

Этот проект охватывает важные темы локального хранения и делегирования событий. Используя локальное хранилище, я могу ввести значение на экран, обновить страницу, и значение останется там. Почему или как спросите вы? Вся информация, относящаяся к этому объекту, сохраняется в локальной памяти браузера. Следующая тема — делегирование событий — помогает нам нацеливать элементы для добавления прослушивателей событий, потому что, если элемент не существует в то время, когда он нацелен, произойдет ошибка.

HTML простой. Есть div-обертка с пустым тегом абзаца, неупорядоченный список и форма с двумя элементами ввода — text и submit.

Единственное, что стоит отметить в CSS, это настройка полей ввода. Бос делает это, добавляя к входному классу «отображение», равное «нет». Затем он устанавливает содержимое до того, как поле будет проверено, на другой стиль поля ввода, а содержимое после — на тако. Я включил CSS здесь:

.tasks input {
display: none;
}
.tasks input + label:before {
content: ‘⬜️’;
margin-right: 10px;
}
.tasks input:checked + label:before {
content: ‘🌮’;

В файле Javascript первое, что мы делаем, — это нацеливаем элемент формы для добавления элементов и неупорядоченный список, в котором элементы будут отображаться. Все объекты данных будут храниться в массиве, который позже будет сохранен в локальном хранилище.

Когда кто-то отправляет элемент, мы запускаем функцию addItem с объектом события, переданным в качестве параметра. Страница перезагружается при отправке, обычно для отправки этой информации во внешний источник, но поскольку мы делаем все это на стороне клиента, мы сначала вызываем «event.preventDefault». Затем мы создаем объект элемента, который будет передан нашим элементам. множество.

Объект будет состоять из двух ключей. Первое — это текстовое значение, отправленное пользователем — полученное путем таргетинга ввода в форме — а второе — логическое значение, используемое для определения того, был ли элемент проверен или нет. После того, как данные были отправлены, нам нужно очистить ввод, сбросив форму. В настоящее время информация не сохраняется при перезагрузке, но нам нужно создать новую функцию для отображения информации.

Мы помещаем функцию «populateList» в функцию «addItem» после того, как элемент был помещен в массив элементов. Массив элементов будет параметром для функции populateList. Итак, каждый раз, когда мы добавляем элемент, функция populateList будет создавать HTML для его отображения.

Функция populateList принимает два параметра — набор параметров, равный пустому массиву, и переменную, предназначенную для неупорядоченного списка. Первый параметр устанавливается равным пустому массиву, чтобы мы могли использовать функцию «карта», даже если массив не существует. Мы устанавливаем innerHTML неупорядоченного списка равным отображаемому массиву, отслеживая значение индекса, который возвращает данные, вложенные в форматированную строку HTML. Код для можно увидеть ниже:

function populateList(items = [], itemsList) {
itemsList.innerHTML = items.map((item, i) =› {
return `
‹li›
‹input type=”checkbox” data-index=${i} id=”item${i}” ${item.done ? 'checked' : ''}›‹/input›
‹метка для =”item${i}”› ${item.text} ‹/label›
‹/li›
`;
}).join(''); //преобразовать массив в строку

В конце каждого ввода находится проверенное состояние. Значение по умолчанию для этого состояния — false. Чтобы он обновлялся при изменении значения, мы используем тернарный оператор и логическое значение в объекте элемента. Если элемент выполнен, то состояние будет установлено как проверено, если нет, оно вернется к значению по умолчанию. Чтобы убедиться, что флажок обновлен для текста, к которому он относится, мы устанавливаем идентификатор ввода и метку «для» равными одному и тому же значению — индексу элемента массива. Кроме того, мы добавляем «индекс данных», равный индексу во входном элементе. «Индекс данных» будет использоваться в более поздней функции для обновления значения «item.done» при нажатии на ввод.

Функция toggleDone обновит входное значение в локальном хранилище до его текущего состояния проверки. Чтобы это работало, нам нужно прикрепить прослушиватели событий ко всем флажкам. Однако может быть время, когда на странице нет флажка. Чтобы решить эту проблему, мы используем делегирование событий и нацеливаемся на элемент, который не только содержит все флажки, но и всегда будет на странице. Этот элемент представляет собой неупорядоченный список, при щелчке по которому прослушиватель событий перенаправляется на флажок внутри него и запускает toggleFunction.

Первая строка функции проверяет, является ли цель вводом, если это не так, функция прекращает работу, но если это так, мы используем вышеупомянутый «индекс данных», чтобы изменить значение конкретного ввода. Код, необходимый для изменения определенного значения ввода с проверенного на непроверенное или наоборот, выглядит следующим образом:

if (!event.target.matches(‘input’)) return;
const el = event.target;
const index = el.dataset.index;
items[index].done = !items[index].done;
localStorage.setItem('items', JSON.stringify(items));
populateList(items, itemsList);

Наконец, мы установим обновленную информацию в локальное хранилище, чтобы придать постоянное состояние данным, добавленным или измененным в функциях addItem или toggleCheck. Хотя локальное хранилище может выглядеть как объект, на самом деле это просто хранилище ключей и значений. Чтобы установить элементы, нам нужно преобразовать элементы в строку, используя JSON.stringify. Код, используемый для этого, показан ниже:

localStorage.setItem('items', JSON.stringify(items));

Чтобы убедиться, что список заполняется при загрузке страницы, мы запускаем «populateItems (items, itemsList)», но для этого нам нужно будет проанализировать информацию в локальном хранилище. Итак, мы возвращаемся к массиву «items» и переопределяем его как

JSON.parse(localStorage.getItems(items)) || [];

Это дает пользователю постоянное состояние для своих данных, когда страница перезагружается, путем преобразования строки JSON обратно в массив, и если в паре ключ-значение «элементы» нет элементов, тогда «элементы» просто будут установлены в пустое значение. множество.

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

Эффект перемещения мыши с тенью текста CSS —

Эффект перемещения мыши в тени текста создается с помощью прослушивателя событий mousemove и небольшого количества математических вычислений. В итоге тень должна двигаться соответственно положению мыши на странице. Чем дальше мышь от текста, тем дальше будет распространяться тень в другом направлении.

В файле HTML просто есть контейнер div с тегом h1 внутри него.

Для CSS я добавил текстовую тень к элементу h1.

Первое, что мы делаем с нашим Javascript, — это определяем наши переменные, которые являются двумя целевыми элементами — элементом контейнера и тегом h1 — и значением, которое относится к расстоянию, на которое тень может отделиться от текста — определяется как «прогулка Затем в контейнер div добавляется прослушиватель событий mousemove, который запускает функцию shadow при срабатывании.

Функция «shadow» начинается с использования «offsetWidth» и «offsetHeight», чтобы найти ширину и высоту контейнера div. Затем мы получаем положение мыши с помощью «event.offsetX» и «event.offsetY» и устанавливаем их равными переменным x и y. Эти последние шаги можно выполнить с помощью деструктурирующего форматирования ES6:

const { offsetWidth: ширина, offsetHeight: высота } = hero;
let { offsetX: x, offsetY: y } = событие;

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

Если дочерний элемент существует, то значения x и y будут приближаться к (0,0) по мере приближения мыши к этому элементу. Чтобы сделать положение согласованным во всем элементе-контейнере, мы удостоверяемся, что «это» — элемент, к которому прикреплен слушатель, — равно «event.target» — элементу, который разделяет текущую позицию с мышью. Если «this» и «event.target» не равны, то мы смещаем положение мыши на размеры дочернего элемента, как показано в коде ниже:

if (this !== event.target) {
x = x + event.target.offsetLeft;
у = у + event.target.offsetTop;

После компенсации любых дочерних элементов нам нужно использовать наше значение «прогулки», которое влияет на тень текста, и связать его с нашей позицией по осям x и y. Наша цель состоит в том, чтобы верхний левый угол был отрицательным (-50), а нижний правый угол был положительным (50) с общим расстоянием 100 пикселей. Это достигается за счет следующих вычислений:

const xWalk = Math.round((x / ширина * прогулка) — (прогулка / 2));
const yWalk = Math.round((y / высота * прогулка) — (прогулка / 2));

Как только эти значения определены, мы включаем их в свойство text-shadow следующим образом:

text.style.textShadow = `${xWalk}px ${yWalk}px 0 rgba(255, 0, 255, 0,7)`;

Когда наша мышь перемещается вокруг элемента-контейнера, расстояние и степень свойства text-shadow будут обновляться.

Чтобы увидеть код целиком, нажмите здесь.

Сортировка названий групп без артиклей —

В этом упражнении мы научимся удалять артикли (A, An, The) и сортировать полученный список по алфавиту. Фишка в том, что когда мы выводим список на экран, статьи все равно будут там.

HTML состоит только из элемента неупорядоченного списка.

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

Javascript состоит из массива имен групп и функции «полоса». ]/i', с пустым значением, ''. Возвращаемое значение — это строка, удаленная из всех статей, и с помощью «обрезки» мы удалили все пробелы. Далее мы сортируем массив названий бэндов и присваиваем его переменной следующим образом:

const sortedBands = bands.sort((a,b) =› полоса (a) › полоса (b) ? 1 : -1)

После того, как названия бэндов отсортированы по алфавиту без статей, мы нацеливаемся на неупорядоченный список и устанавливаем его innerHTML равным:

sortedBands.map(band =› `‹li›${band}‹/li›`).join(‘’);

Чтобы увидеть код на моей странице GitHub, нажмите здесь.

Подсчет количества строк с уменьшением —

В этом уроке мы преобразуем строки времени в общее количество секунд, а затем используем сокращение, чтобы получить общее время для всех видео.

HTML состоит из неупорядоченного списка, элементы которого включают свойство «дата-время», равное строке длины видео.

Для этого проекта нет CSS.

В Javascript мы сначала нацеливаем все элементы списка со свойством «data-» и копируем их в пустой массив. Мы устанавливаем этот массив равным переменной «timeNodes». Затем мы сопоставляем массив, чтобы получить время для каждого видео. Когда у нас есть время, мы деконструируем минуты и секунды и преобразуем строки в числа. Затем минуты умножаются на 60 и добавляются к секундам. Теперь, когда все время преобразовано в секунды, мы используем сокращение, чтобы получить общее количество секунд для всех видео. Поскольку это время установлено равным переменной «const», мы определяем переменную «secondsLeft» и используем «let» для ее определения. Мы манипулируем этой переменной, чтобы получить общее количество часов, минут, а любое оставшееся значение будет общим количеством секунд.

Чтобы увидеть код, нажмите здесь.

Нереальное веселье перед вебкамерой —

Веб-камера использует холст и видеоэлементы вместе с веб-камерой пользователя, чтобы делать снимки и отображать изображения в отдельной полосе.

HTML не только содержит элементы холста и видео, но также имеет три отдельных входных диапазона для настройки насыщенности красного, синего и зеленого цветов изображений.

CSS не содержит ничего нового, перейдем к Javascript.

Для начала нам нужно создать локальный хост-сервер для этого проекта. Bos включает файл package.json в начальные файлы, если вы не можете создать свой собственный. Я мучился с этой частью проекта, и если у вас возникли проблемы, то предлагаю вам посмотреть документацию по npm по этой теме. Если это не помогло, или вы все еще не знакомы с терминалом, я предлагаю вам пройти курс Bos Command Line Power User.

После того, как все это будет сделано, вы запускаете Javascript, ориентируясь на элементы HTML. Видео, полоса фотографий, аудио, холст и его контекст являются целевыми и назначаются переменным.

Затем мы хотим, чтобы вход с камеры отображался в элементе видео при загрузке страницы. Это делается в функции «getVideo» с помощью следующей строки кода:

navigator.mediaDevices.getUserMedia({видео: правда, аудио: ложь})

Это вернет обещание, которое дает нам объект данных, который необходимо установить в качестве источника видео. Чтобы это работало, нам нужно преобразовать объект в строку URL. Вы можете сделать это, используя следующий метод:

video.src = window.URL.createObjectURL(localMediaStream)

После того, как у видео есть действительный источник, мы вызываем «video.play()». Не забудьте добавить метод «поймать» ошибку в случаях, когда пользователь отказывает в разрешении на использование своей веб-камеры. Для следующей части этого проекта нам нужно взять изображение из видео и нарисовать его на холсте.

Функция, которая делает вышеупомянутое, называется «paintToCanvas». Во-первых, нам нужно убедиться, что размеры холста соответствуют размерам видео, установив ширину и высоту видео равными переменным, которые мы позже назначим для те же свойства холста. Затем мы возвращаем функцию setInterval, которая будет брать изображение каждую n-ю миллисекунду и помещать его на холст. Мы используем return перед интервалом, чтобы иметь возможность очистить его, если нам когда-нибудь понадобится.

Внутри интервала мы берем наш (2d) контекст для холста и запускаем метод для рисования изображения, причем изображение является видеоэлементом. Остальные аргументы обозначают начальную позицию ((0,0) или верхний левый угол холста) и переменные ширины и высоты, которые мы определили ранее. Чтобы убедиться, что это работает на pageLoad, мы присоединяем прослушиватель событий к элементу видео. Когда видео передает свойство canplay, оно будет нарисовано на холсте. Теперь давайте сделаем фото.

Функция «takePhoto» прикреплена к кнопке в HTML и будет воспроизводить звук при нажатии. Сначала мы извлекаем данные из изображения с помощью метода toDataURL и присваиваем их переменной data. Этот процесс выполняется с помощью следующего кода:

const data = canvas.toDataURL(‘image/jpeg’)

Мы помещаем эти данные во вновь созданную якорную ссылку, которая будет выводиться в наш div с полосой фотографий. Каждый тег привязки будет иметь атрибут загрузки, который позволит вам сохранить изображение. Чтобы вывести тег привязки в div полосы фотографий, мы используем метод, аналогичный «prepend» jQuery, который называется «insertBefore». Последнее, что мы делаем, — убеждаемся, что внутренний HTML-код тега привязки равен фотографии. Весь этот процесс на Javascript выглядит так:

const link = document.createElement('a');
ссылка.href = данные;
link.setAttribute(‘скачать’, ‘ты такая красивая’);
link.innerHTML = `‹img src='${data}' alt='ты такая красивая'›‹/img›`
strip.insertBefore(link, strip.firstChild);

Итак, когда вы запускаете «takePhoto», изображение будет отображаться в разделе div полосы фотографий, и если вы хотите загрузить любой из них, все, что вам нужно сделать, это щелкнуть изображение в полосе.

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

Встроенное распознавание речи —

В этом проекте используется свойство браузера SpeechRecognition для перевода речи в текст.

HTML состоит из элемента div с классом «words» и свойством «contenteditable» — это означает, что любые переведенные слова могут быть изменены пользователем.

Бос использует CSS, с которым я не был знаком, чтобы сделать word-div похожим на лист бумаги. Я включил код ниже:

.words {
max-width: 500px;
margin: 50px auto;
background: white;
border-radius: 5px;
box-shadow : 10px 10px 0 rgba(0, 0, 0, 0.1);
background: -webkit-gradient(linear, 0 0, 0 100%, from(#d9eaf3), color-stop(4%, #fff) )) 0 4px;
padding: 3.75rem 2rem 1rem 5rem;
background-size: 100% 3rem;
position: relative;
line-height: 3rem;
>

.words:before {
содержимое: ‘’;
позиция: абсолютная;
ширина: 4 пикселя;
верх: 0;
слева: 30 пикселей;
внизу: 0;
граница: сплошная 1 пиксель;
цвет границы: прозрачный #efe4e4;

Первые несколько свойств класса «words» устанавливают размеры страницы и цвет фона на белый. Следующими важными свойствами для достижения этого эффекта являются background, padding и background-size.

Фон использует более старый повторяющийся градиент, совместимый с Safari 4, Chrome 1–9, iOS 3.2–4.3, Android 2.1–3.0. Метод "-webkit-gradient", а также методы "from" и "color-stop" позволяют идентифицировать старый метод. Что происходит в этом свойстве, так это то, что линейный градиент задается от верхнего левого угла элемента к нижнему левому краю — положение x остается постоянным. Градиент останется белым на 96% длины и сместится на оставшиеся 4% в другой цвет по координатам на элементе — (0,4). Отступы увеличат размер элемента и придадут линиям на линованной бумаге эффект большей высоты и ширины. Так как это повторяющийся градиент, мы хотим изменить размер фона. Ширина каждого градиента будет равна 100%, а высота всего 3rem.

Последний аспект эффекта разлинованной бумаги, который нам нужно включить, — это двойные линии, идущие вертикально вниз по странице. Для этого мы добавляем класс «words:before», который будет вставлять свойства элемента перед div «words». Класс — это просто маленькая коробка с серой прозрачной рамкой. Поскольку элементы повторяются, границы будут выглядеть как вертикальные линии вниз по странице. На этом CSS заканчивается, давайте посмотрим, что происходит с Javascript.

Прежде чем мы начнем, обязательно пропустите ваш HTML-файл через сервер — без него распознавание голоса работать не будет.

Первое, что мы делаем, — это присваиваем переменной глобальное свойство «window.SpeechRecognition» или «window.webkitSpeechRecognition» — эти два имени представляют разный синтаксис для Firefox и Chrome. Затем мы создаем новый экземпляр распознавания речи и присваиваем его переменной «распознавание». Мы используем переменную «распознавание» и присваиваем методу «interimResults» значение true. Это будет заполнять значения, когда вы говорите, а не отображать результаты, когда вы закончите говорить. Затем мы назначаем переменную «p», используя «let», равную вновь созданному элементу абзаца. Элемент абзаца будет создаваться каждый раз, когда в разговоре будет перерыв. Мы также назначаем переменную «words», используя «let», равную div «words», и добавляем теги абзаца к div «words».

Обязательно поместите «recognition.start()» в конце страницы, чтобы сообщить пользователю, что нам нужно разрешение на использование его микрофона, без этого на странице не будет результатов.

Объекту «распознавание» будет назначен прослушиватель событий, который будет прослушивать «результат» и при срабатывании возвращать событие. Мы передаем событие через анонимную функцию, которая возвращает результаты. Результатом является вложенный объект, который будет включать расшифровку сказанного. Проблема в том, что нам нужно преобразовать эти результаты в массив.

Мы создадим новый массив, используя оператор распространения для содержимого «event.results». Затем мы сопоставляем каждый объект в массиве, чтобы получить первый результат каждого объекта. Затем сопоставьте этот массив, чтобы получить стенограмму того, что было сказано, и соедините вновь сформированный массив в строку. Весь этот процесс в коде показан ниже:

const Transcript = […event.results]
.map(result =› result[0])
.map(result =› result.transcript)
.join(“” );

После создания транскрипта мы устанавливаем его равным текстовому содержимому тега абзаца. В этот момент вы должны начать видеть стенограмму в DOM, но после паузы функция перестанет работать, и если это произойдет, новый элемент абзаца перезапишет любой существующий контент.

Чтобы решить первую проблему, мы создаем второй прослушиватель событий с прослушивателем «конец» и запускаемой функцией «распознавание.старт». теги абзаца. Эта проблема решается путем проверки того, являются ли результаты окончательными, с использованием свойства isFinal объекта события. Если говорящий закончил говорить, мы перезаписываем существующую переменную «p» и назначаем ей только что созданный элемент абзаца, а затем добавляем его в div «words». Вот код условного выражения:

if (event.results[0].isFinal) {
p = document.createElement(“p”);
words.appendChild(p);

}

Это охватывает основы распознавания речи. В видео Бос показывает базовый пример того, как мы можем использовать это, чтобы вызвать какое-то действие или функцию. Итак, я решил сделать это с помощью нескольких команд, которые открывают некоторые веб-страницы (Facebook, YouTube, GitHub). Я также включаю кнопку сохранения, чтобы сохранить стенограмму. Вы можете проверить этот проект на CodePen.

Спидометр и компас на основе геолокации —

В этом проекте мы используем геолокацию для определения направления и скорости. Мы также использовали безопасный источник или локальный хост, а также симулятор iPhone от xCode, чтобы все работало правильно. После размещения безопасного источника в симуляторе мы используем различные места и скорости перемещения, которые может предложить xCode, чтобы продемонстрировать функциональность приложения. Сейчас я покажу вам, как работает приложение.

HTML состоит из элемента изображения для компаса, элемента h1, который содержит два элемента span для скорости и единиц измерения скорости.

CSS включает в себя этот пунктирный фон, который мне показался довольно крутым. Я включил код ниже:

фон:
радиальный градиент(черный 5%, прозрачный 16%) 0 0,
радиальный градиент(черный 5%, прозрачный 16%) 8 пикселей 8 пикселей,
радиальный градиент (rgba(255,255,255,.1) 5%, прозрачность 20%) 0 1px,
radial-gradient(rgba(255,255,255,.1) 5%, прозрачность 20%) 8px 9px;
background-color : #F2F2F2;
размер фона: 16 пикселей 16 пикселей;

Код довольно понятен. У радиального градиента есть начальная точка и цвет и конечная точка и цвет. Следующие два значения — это ширина и высота этого конкретного градиента. Если изменить размер фона на 16px 16px, точки будут уменьшаться, а фон будет повторяться, закрывая весь экран. Теперь давайте сделаем немного Javascript.

Перво-наперво, нам нужно нацелить и назначить две переменные для стрелки и значения скорости. После этого мы используем «navigator.geolocation.watchPosition()» для отслеживания позиции пользователя. Небольшое замечание о разнице между watchPosition и getCurrentPosition: первый отслеживает положение с течением времени и предоставляет нам данные так часто, как нам это нужно, а второй возвращает только один результат для геолокации пользователя. Метод watchPosition примет параметр данных и вернет нам некоторые полезные данные геолокации. Для этого приложения мы будем использовать «заголовок», который сообщает нам наше направление относительно севера, и значения «скорости» в км/ч — поскольку я из США, я изменил это значение на мили в час.

Значение «скорости» устанавливается равным текстовому содержимому первого элемента span. «Направление» используется в качестве градусов для поворота компаса. Два процесса выполняются в коде ниже:

speed.textContent = Math.round(data.coords.speed * 0,6214);

arrow.style.transform = `rotate(${data.coords.heading}deg)`;

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

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

Перейти по ссылкам —

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

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

В CSS нет ничего нового или примечательного, поэтому давайте перейдем к Javascript.

Первое, что мы делаем, это нацеливаемся на все теги привязки и создаем элемент span, который будет иметь класс «highlight», и добавляем его в DOM. Оба они назначены переменным, а первый присоединен к прослушивателю событий. Когда мышь входит в один из этих тегов привязки, будет инициировано событие и будет запущена функция «highlightLink».

Функция HighlightLink получает размеры и координаты целевого тега привязки. Используя this и getBoundingClientRect, мы можем получить нижнюю, левую, правую и верхнюю координаты, а также высоту и ширину конкретного элемента. Затем мы создаем объект со свойствами width, height, top и left и корректируем значения последних двух в зависимости от того, насколько далеко мы прокручиваем страницу. Объект «координаты» должен выглядеть так:

const coords = {
width: linkCoords.width,
height: linkCoords.height,
top: linkCoords.top + window.scrollY,
left: linkCoords.left + окно.scrollX,
};

Затем мы берем элемент span и присваиваем ему эти значения, поэтому, когда пользователь вводит элемент, свойства класса «highlight» изменятся, чтобы соответствовать содержимому тега привязки. Вот код для изменения размеров элемента span:

highlight.style.width = `${coords.width}px`;
highlight.style.height = `${coords.height}px`;
highlight.style.transform = `translate(${coords.left}px, ${coords.top}px)` ;

Этого достаточно для этого проекта, давайте перейдем к следующему. Нажмите здесь для моего кода на GitHub.

Синтез речи —

В этом проекте используется API-интерфейс синтеза речи, который есть в большинстве современных браузеров, для передачи текста, который мы вводим в текстовую область. Мы также даем вам возможность изменить голос говорящего, а также скорость и высоту тона, с которыми он говорит.

HTML состоит из контейнера div и внутри него выпадающего меню с использованием тегов select и option, метки и ввода для скорости и высоты тона, текстовой области и двух кнопок для функций говорить и останавливаться. Важным аспектом HTML являются имена входных данных — шаг и скорость. Эти имена будут соответствовать именам свойств объекта произнесения синтеза речи.

CSS включает в себя уникальный фон, используя свойство radiant-circle и circle-at. Код слишком длинный, чтобы включать его, но вы можете увидеть его в CSS-файле для этого проекта на моей странице GitHub. Еще одним новым для меня свойством стал селектор nth-of-type selector(n), который соответствует каждому элементу, являющемуся n-м дочерним элементом определенного типа своего родителя. Разница между этим и селектором nth-child заключается в том, что последний соответствует каждому n-му элементу независимо от типа.

В файле Javascript первое, что мы делаем, — это создаем экземпляр объекта произнесения синтеза речи и присваиваем его переменной. Затем мы нацеливаемся на раскрывающееся меню голоса, два ввода диапазона, текстовую область и две кнопки. Последняя переменная, которую мы создаем, — это массив «voices», использующий «let» для хранения различных параметров голоса. Там много чего происходит, поэтому я включил следующие переменные:

const msg = new SpeechSynthesisUtterance(); //API синтеза речи
const voicesDropDown = document.querySelector(‘[name=”voice”]’);
const options = document.querySelectorAll(‘[type=”range”], [name=”text”]’);
const speakButton = document.querySelector(‘#speak’);
const stopButton = document.querySelector('#stop');
пусть голоса = [];

Переменная «msg», содержащая экземпляр «SpeechSynthesisUtterance», будет создаваться каждый раз, когда мы хотим, чтобы говорящий говорил, и содержать информацию о текстовом содержании, голосе, скорости и высоте тона, которые мы выбрали для речи.

Первое, что мы делаем, это назначаем текст в текстовой области свойству text объекта «msg».

msg.text = document.querySelector(‘[name="text"]’).value;

Теперь, когда текст находится в экземпляре «SpeechSynthesisUtterance», нам нужно присвоить переменной «msg» голос.

Мы присоединяем к объекту «SpeechSynthesis», который находится в браузере, прослушиватель событий с событием «voiceschanged», которое запускает функцию «populateVoices» при срабатывании. Функция «populateVoices» сначала переопределит массив «voices» и будет установлена ​​равной «this.getVoices()», которая заполняет массив списком различных голосов. Затем мы хотим сопоставить голоса и установить их в качестве параметров в раскрывающемся меню голосов.

voicesDropDown.innerHTML = voices .map(voice =›

`‹option value="${voice.name}"›${voice.name} (${voice.lang})‹/option›`)
.join('');

Теперь нам нужно прикрепить голос к переменной «msg». Итак, мы присоединяем прослушиватель событий к voicesDropDown, который будет прослушивать событие изменения, запускающее функцию setVoice.

Функция «setVoice» примет свойство «голос» объекта «msg» и установит его равным «voices.find(voice =› voice.name === this.value)». Этот код будет перебирать массив голосов. и найти имя голоса, которое равно значению, выбранному пользователем. Последнее, что мы делаем в функции «setVoice», — это вызываем функцию «переключатель», чтобы остановить динамик, когда мы меняем голос.

Первое, что делает функция «переключатель», — это останавливает все, что в данный момент говорит, с помощью метода «отмена()» объекта «speechSyntheis». Чтобы убедиться, что говорящий остановился, мы передаем флаговую переменную startOver в качестве параметра. Если это так, то мы можем снова запустить динамик, используя следующий код: «speechSynthesis.speak(msg)». Функция «переключатель» также прикреплена к кнопкам «говорить» и «стоп», которые имеют прослушиватель событий «щелчок». Когда мы нажимаем кнопку «стоп», для переменной флага или аргумента функции устанавливается значение false.

Наша последняя функция привязана ко всем диапазонным и текстовым вводам. Когда событие «change» запускается, функция «setOption» берет имя ввода, которое было назначено в HTML, находит его в объекте «msg» и устанавливает его равным новому значению этого ввода. Если одно из этих значений изменено и к экземпляру «SpeechSynthesisUtterance» добавлено новое значение, то будет вызвана функция «переключатель», чтобы остановить старую речь и запустить новую. Функция состоит всего из двух строк и показана ниже:

msg[this.name] = this.value;
переключить();

К проекту в целом, нажмите здесь, чтобы увидеть его на моей странице GitHub.

Закрепленная навигация —

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

HTML состоит из раздела заголовка с тегом h1, элемента навигации, который инкапсулирует неупорядоченный список, и элемента div с некоторым текстом.

В CSS у логотипа определено большинство свойств, но максимальная ширина равна нулю. Когда пользователь прокручивает страницу до определенной точки, мы добавляем класс «fixed-nav», который изменяет ширину логотипа на 500 пикселей. Некоторые другие элементы, которые меняются в этот момент, — это элемент nav, который меняет отображение на гибкий и получает тень, а также элемент div text-wrap, который трансформируется в масштаб, равный единице. Теперь давайте определим точку разграничения, где эти свойства изменяются.

В Javascript определены две переменные — переменная «nav», которая нацелена на элемент навигации, и переменная «topOfNav», равная тому, где на экране находится верхняя часть панели навигации. Мы присоединяем прослушиватель событий «прокрутки» к окну, который при срабатывании запускает функцию «fixNav».

Функция «fixNav» использует условное выражение, которое сравнивает значение «topOfNav» с тем, насколько далеко вниз прокрутил страницу пользователь. Чтобы получить последнюю часть информации, мы используем «window.scrollY». Если пользователь прокрутил верхнюю часть панели навигации, мы добавляем класс «fixed-nav» в тело. Нацеливая тело вместо элемента nav, мы можем нацеливаться на другие элементы внутри этого родительского элемента. Мы также добавляем отступы к телу, чтобы приспособиться к изменению положения с относительного на фиксированное.

Когда мы прокручиваем панель навигации, она больше не будет занимать место на странице, что вызывает перекомпоновку остального контента. Чтобы содержимое не подскакивало и не занимало место, где находилась панель навигации, мы добавляем отступ к верхней части тела, равный высоте элемента. С другой стороны условного выражения, если позиция прокрутки пользователя меньше, чем точка, в которой находится верхняя часть панели навигации, мы удаляем класс «fixed-nav» и устанавливаем верхний отступ равным нулю. Оператор if-else должен выглядеть так:

if (window.scrollY ›= topOfNav) {
document.body.style.paddingTop = nav.offsetHeight + ‘px’;
document.body.classList.add('fixed-nav');
} else {
document.body.style.paddingTop = 0;
document.body.classList.remove('fixed-nav');

Чтобы перейти к проекту целиком, нажмите здесь.

Захват событий, распространение, всплытие и один раз —

В этом упражнении рассматриваются прослушиватели событий и то, что происходит с захватом событий и всплывающей подсказкой, а также метод «stopPropagation» и новое свойство с именем Once.

HTML состоит из внешнего div, внутреннего div и самого внутреннего div с разными именами классов — «один», «два», «три» соответственно.

В CSS нет ничего особенного, в Javascript.

В Javascript мы ориентируемся на все элементы div и добавляем прослушиватель событий «щелчок», который запускает функцию «logText». Когда нажимается элемент div, мы записываем в консоль следующее значение: «this.classList.value». Это говорит нам о том, что вызывает событие.

Сначала мы рассмотрим процесс «захвата». При нажатии на элемент div «3» браузер сначала захватит все элементы, окружающие элемент div — «body», «1», «2». Другими словами, когда элемент является целевым, все родительские элементы будут зарегистрированы в первую очередь. По умолчанию для этого свойства установлено значение false, но его можно изменить в прослушивателе событий. Если true, функция будет регистрировать значения сверху вниз и предотвращать всплывающий процесс.

Бублирование происходит после захвата и идет в обратном порядке. Когда мы щелкаем div 3, событие срабатывает для этого элемента, а затем срабатывает для всех его родительских элементов — 2, 1, body и т. д. Этот процесс всплытия происходит с почти все обработчики событий, и остановить их можно только одним способом.

Метод «stopPropagation» используется для предотвращения запуска события в родительских элементах цели. Когда мы добавим метод к инициированному событию, функция «logText» будет регистрировать только тот элемент, который был выбран. Если мы щелкнем div «2», будет зарегистрировано только имя класса «tw0» — без всплытия. Этот метод также можно использовать, когда значение захвата равно true, и если щелкнуть элемент div «3», функция зарегистрирует элемент «1». Функция запускается для первого элемента, который запускает событие, которое изменяется со значением захвата, а «stopPropagation» завершает процесс.

Последним, что было рассмотрено в этом уроке, было новое свойство once. Когда для этого свойства установлено значение true, в прослушивателе событий функция может быть запущена только один раз. Таким образом, если для захвата и один раз установлено значение true, а элемент 3 щелкнут, функция зарегистрирует три два один. Теперь, когда функция запущена один раз, прослушиватель событий отвяжется от элемента. Приведенный выше сценарий может быть реализован с помощью следующего кода:

divs.forEach(div =› div.addEventListener(‘click’, logText, {
захватить: true,
один раз: true
}));

Это все для этого урока. Чтобы увидеть код из этого урока нажмите здесь.

Раскрывающееся меню «Полосатый след» —

Этот проект основан на том, что мы узнали из урока Переход по ссылкам, и применяет его к раскрывающемуся меню. Мы пытаемся имитировать меню навигации на сайте Stripe. Ключом к проекту является получение общей площади содержимого каждого элемента раскрывающегося списка и применение этих размеров к фону раскрывающегося списка.

В файле HTML у нас будет элемент навигации, который содержит элемент div для раскрывающегося фона и неупорядоченный список.

CSS включает в себя два новых для меня свойства. Первое свойство называется перспектива. Перспектива определяет, на сколько пикселей 3D-элемент помещается из вида. Другими словами, это свойство позволяет изменить перспективу просмотра 3D-элементов. Другое свойство называется will-change. Will-change оптимизирует анимацию, сообщая браузеру, какими свойствами и элементами предстоит управлять, потенциально увеличивая производительность этой конкретной операции. Теперь давайте рассмотрим Javascript.

Первое, что мы делаем, это нацеливаем все триггеры или прямые потомки (элементы списка) неупорядоченного списка с классом «круто». Мы также должны нацелить белый div, который будет фоном для каждого раскрывающегося списка. , а также элемент навигации. Далее мы должны прикрепить прослушиватели событий к элементам списка.

Для каждого триггера нам понадобится слушатель mouseenter и mouseleave. Когда мышь входит в элемент списка, запускается функция «handleEnter»; и аналогичным образом, когда запускается событие «mouseleave», будет запущена функция «handleLeave».

Функция «handleEnter» прикрепляет класс «trigger-enter» к целевому элементу списка. Класс «trigger-enter» изменит содержимое с display none на display block. Следующий фрагмент кода определит, содержит ли элемент списка класс «триггер-ввод». Если это так, к тому же элементу присоединяется класс «trigger-enter-active», который переводит непрозрачность элемента списка в 1. Условное и последующее действие содержатся в «setTimeout», который запускается через 150 миллисекунд. Функция setTimeout должна выглядеть так:

setTimeout(() =› this.classList.contains(‘trigger-enter’) && this.classList.add(‘trigger-enter-active’), 150);

Чтобы «это» было равно элементу списка, нам нужно содержать его в стрелочной функции. Обычная функция установит this равным объекту окна. Задержка в 150 миллисекунд гарантирует, что содержимое элемента списка появится на странице после установки фона. Затем мы прикрепляем к фону «открытый» класс, который сделает фон для выпадающего содержимого видимым и на странице. Следующая часть этой функции влечет за собой приведение белого фона в соответствие с содержимым элемента списка.

Во-первых, мы нацеливаем раскрывающееся содержимое и назначаем его переменной. Затем мы получаем размеры или координаты целевого контента, используя getBoundingClientRect, вместе с размерами элемента навигации. Последний набор координат будет использоваться для настройки любого содержимого, которое может находиться над элементом навигации. Мы компенсируем пространство, создавая новый объект «координаты», как показано ниже:

const coords = {
height: dropdownCoords.height,
width: dropdownCoords.width,
top: dropdownCoords.top — navCoords.top,
left: dropdownCoords.left — navCoords.left

Как видите, свойства top и left были скорректированы для любого содержимого, которое может нарушить выравнивание раскрывающегося содержимого и его фона. Теперь, когда у нас есть эти скорректированные координаты, мы можем применить их к фону:

background.style.setProperty('width', `${coords.width}px`);
background.style.setProperty('height', `${coords.height}px`);
background.style.setProperty(‘transform’, `translate(${coords.left}px, ${coords.top}px)`);

Это должно охватывать весь код функции «handleEnter», функция, запускаемая событием «mouseleave», очень проста.

Функция «handleLeave» просто удалит классы, которые мы прикрепили в функции «handleEnter». Классы «trigger-enter» и «trigger-enter-active» удаляются из некогда целевого элемента списка; также фон потеряет класс «открытый».

Это должно сделать это для этого проекта. Проверьте мой код здесь. Мы переходим к следующему.

Нажмите и перетащите для прокрутки —

Проект Click and Drag to Scroll представляет собой уникальный способ отображения серии слайдов. Эта функция реализована с помощью нескольких слушателей событий и получения позиций на странице.

Наш HTML будет включать в себя контейнер div и ряд div внутри контейнера div, которые представляют слайды.

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

Далее у нас есть свойство white-space: nowrap. White-space указывает, как следует обрабатывать пробелы внутри элемента. Обычно последовательности пробелов сворачиваются в один пробел, а текст при необходимости переносится. Однако nowrap будет иметь последовательности пробелов, свернутых в один пробел. Текст никогда не будет переноситься на следующую строку. Текст продолжается на той же строке, пока не встретится тег ‹br›.

Еще одно важное свойство — user-select: none. Оно управляет фактической операцией выбора и по умолчанию определяется браузером. Значение none означает, что текст элемента и подэлементов нельзя будет выбрать.

В дополнение к вышеперечисленным свойствам важным свойством было свойство display: inline-flex, которое, по моему мнению, требовало более четкого определения, чтобы отличить его от display: flex. Inline-flex не делает гибкие элементы отображаются встроенными. Он заставляет flex-контейнер отображаться встроенным. Это единственная разница между inline-flex и flex. Аналогичное сравнение можно провести между встроенным блоком и блоком, а также любым другим типом отображения, имеющим встроенный аналог.

Последнее свойство — «item:nth-child», которое позволяет нам ориентироваться на каждый отдельный слайд, а также на все четные и нечетные слайды. Когда мы нацеливаемся на четные слайды, мы устанавливаем преобразование для поворота Y-позиции. Затем мы делаем то же самое для нечетных слайдов, но с тем же отрицательным значением преобразования. Это, в дополнение к некоторой перспективе, дает нам эффект сложенной бумаги, показанный на картинке выше. Теперь, когда мы рассмотрели CSS, давайте перейдем к Javascript.

Наша цель — определить по первоначальному щелчку и движению мыши влево или вправо расстояние, на которое мы переместили мышь. Затем мы применяем это расстояние к слайдеру-контейнеру.

Для этого мы нацеливаем слайдер-контейнер и устанавливаем его равным переменной. Используя «let», нам нужно определить три другие переменные — переменную флага, переменную для хранения нашего начального значения и переменную для хранения количества прокрутки влево или вправо. Далее мы прикрепляем прослушиватели событий к слайдеру-контейнеру.

У первого слушателя будет событие mousedown, которое запускает анонимную функцию. Я включил код этой функции ниже:

isDown = истина;
slider.classList.add(‘active’);
startX = event.pageX — slider.offsetLeft;
scrollLeft = slider.scrollLeft;

Эта функция устанавливает флаговую переменную isDown в значение true. Он также добавляет класс «активный» к слайдеру-контейнеру, который меняет цвет фона на непрозрачный белый, курсор на захват и масштаб на единицу. Мы используем аргумент события и метод «pageX», чтобы определить, где на странице мы щелкнули, и «offsetLeft», чтобы настроить значение позиции для любого поля или отступа. Затем мы присваиваем переменной «scrollLeft» величину, которую мы переместили влево или вправо, используя метод «scrollLeft» в контейнере-ползунке. Мы будем использовать это значение «scrollLeft» в нашем последнем прослушивателе событий.

Функции mouseleave и mouseup ничего не делают с ползунком-контейнером. Оба сохраняют переменную флага равной false и удаляют «активный» класс. Мы хотим убедиться, что содержимое остается неизменным при запуске событий.

Наша последняя функция запускается слушателем mousemove и передает аргумент события через анонимную функцию. Код этой функции можно увидеть здесь:

если (!isDown) вернуть;
event.preventDefault();
const x = event.pageX — slider.offsetLeft;
const walk = (x — startX) * 3;
slider.scrollLeft = scrollLeft — ходить;

Мы хотим убедиться, что переменная флага истинна, прежде чем мы запустим эту функцию. Если это не так, мы останавливаем выполнение функции. Если это правда, мы запускаем «event.preventDefault», чтобы пользователь не мог выбрать любой текст, нежелательное скольжение или любое другое незапланированное событие. Далее мы хотим рассчитать нашу позицию по оси x. Переменная «x» сообщает нам, где находится курсор, когда мы двигаемся влево или вправо. Это тот же код для переменной «startX», но нам нужно пересчитывать позицию каждый раз, когда мы перемещаем мышь. Если вы зарегистрируете эти два значения, вы увидите, что переменная «x» изменяется, а переменная «startX» остается привязанной. Переменная «прогулка» указывает, насколько далеко мы отклонились от начальной точки. Мы умножаем значение на три, чтобы ускорить эффект прокрутки. Наша последняя часть этой функции — вычитание значения переменной «walk» из «scrollLeft», вычисленного в первой функции, для перемещения слайдов влево или вправо в контейнере.

Это все для этого проекта. Ознакомьтесь с кодом полностью на моей странице GitHub.

Контроллер скорости видео —

В этом проекте мы создаем инструмент, который будет ускорять или замедлять скорость воспроизведения видео.

Для HTML у нас есть элемент видео и div, полоса скорости внутри div — все это вложено в div-контейнер.

Ничего нового в CSS, перейдем к Javascript.

Первое, что мы делаем в файле Javascript, — определяем наши переменные. Наши переменные включают «скорость», «бар» и «видео» и названы в честь соответствующих целевых элементов. Затем мы присоединяем прослушиватель событий mousemove к div «speed». Инициированное событие будет передано в качестве аргумента через функцию «handleMove».

Эта функция сначала вычисляет, где пользователь нажал на полосу скорости, используя «event.pageY», и вычитает из нее точку, где начинается полоса на странице, заданную «this.offsetTop». Это значение хранится в переменной ‘y’. Затем мы превращаем значение «y» в процентное значение, разделив «y» на высоту полосы «this.offsetHeight» и используя результат для расчета процента «высоты» для нашего стиля. Переменная «высота» равна «процентам», умноженным на сто, округленным до ближайшего целого числа — обязательно добавьте «%» в конце значения. Затем мы устанавливаем это значение равным «bar.style.height», что позволяет нам перетаскивать и размещать заполнитель панели скорости. Наша следующая задача — обновить число воспроизведения в баре.

Нам нужна переменная для минимального и максимального значения. Минимальное значение установлено на 0,4, а максимальное равно 4. Когда высота наполнителя составляет 0% от общей высоты, минимальное значение должно быть 0,4, а когда оно находится на 100% высоты, скорость воспроизведения должна быть 4. Чтобы сделать это, мы используем следующую строку кода:

констная скорость воспроизведения = процент * (макс. — мин.) + мин.

Мы используем это значение, фиксированное до десятичных знаков, как число на панели скорости и как скорость воспроизведения видео. Оба выполняются с использованием этих двух строк кода:

bar.textContent = ‘x’ + воспроизведениеRate.toFixed(2);
video.playbackRate = воспроизведениеRate;

Это должно быть все для этого проекта. Проверьте мой код здесь. Давайте перейдем к следующему.

Таймер обратного отсчета —

В этом уроке показано, как сделать таймер обратного отсчета. Есть время, которое пользователь может выбрать, а также поле ввода для ввода другого количества времени в минутах. Таймер также включает время, когда пользователь должен вернуться после окончания периода.

HTML состоит из контейнера div. Внутри этого есть два div. Первый div предназначен для элементов управления, включая пять кнопок и форму/ввод. Второй div используется для отображения результатов ввода. Существует тег h1 для таймера и тег абзаца для времени, которое нужно вернуть.

CSS использует несколько гибких свойств, но ничего нового. Если вы все еще не уверены в flexbox. Рекомендую пройти курс Боса Что за Flexbox?!.

Для Javascript мы получим временную метку, создадим пару функций для вывода ее в удобочитаемом формате и прикрепим некоторые элементы с прослушивателями событий. Первое, что мы делаем, это создаем функцию под названием «таймер».

Эта функция будет принимать в качестве параметра количество секунд, которые вы хотите пройти, и обновлять это время каждую секунду. Первое, что мы делаем, это определяем переменную «сейчас», которая равна объекту даты с методом сейчас — «Дата.сейчас». Затем мы вычисляем переменную «тогда», которая равна «сейчас» плюс параметр, секунд, умноженное на 1000 — для перевода из секунд в миллисекунды. После определения этих переменных мы определяем наш интервал. Переменная «обратный отсчет» устанавливается равной интервалу, который выполняется каждые 1000 миллисекунд. Внутри интервала наша анонимная функция рассчитает, сколько секунд осталось. Этот расчет выполняется с помощью следующего кода:

const secondLeft = Math.round((then — Date.now()) / 1000);

Затем нам нужно создать условное выражение для запуска действия, когда время достигает нуля. Если секунды меньше нуля, мы очищаем интервал обратного отсчета и останавливаем выполнение функции, что можно увидеть в коде ниже:

if (secondsLeft ‹ 0) {
clearInterval(countdown)
return;

Внутри этой функции нам еще предстоит отображать время, потому что мы не создали функции для этого. Функция «displayEndTime» будет вызвана один раз при первом запуске функции «таймер» или там, где мы определили наши переменные «тогда» и «сейчас». Мы вызываем функцию «displayTimeLeft» дважды, один раз, когда запрашивается функция «таймер», и второй раз в интервале «обратного отсчета».

Функция displayTimeLeft принимает параметр «секунды», преобразует это число в минуты и секунды и отображает результат в виде текстового содержимого элемента h1. Чтобы преобразовать секунды в минуты и секунды, а затем отформатировать их в удобочитаемое время, мы использовали следующий код:

константа минут = Math.floor(секунды / 60);
константа остатка секунд = секунды % 60;
const display = `${минуты}:${оставшиеся секунды ‹ 10 ? ‘0’ : ‘’}${remainderSeconds}`;

После того, как время было переформатировано, мы устанавливаем его равным document.title, который является текстовым содержимым элемента заголовка сайта, и «timerDisplay», который является переменной, назначенной целевому элементу h1.

Наша следующая функция отображения — «displayEndTime», которая отображает время окончания интервала. Он принимает временную метку в качестве параметра и создает новый объект Date из временной метки, назначенной переменной end. Затем мы вызываем методы getHours и getMinutes для объекта Date end, результаты в переменные, «часы» и «минуты», и преобразовать их в читаемый формат. Это преобразование и отображение часов и минут выполняется с помощью следующего кода:

const hour = end.getHours();
const am_pm = hour › 12 ? 'ДО ПОЛУДНЯ, ПОСЛЕ ПОЛУДНЯ';
const AdjustHour = час › 12 ? час — 12 : час;
const минут = end.getMinutes();
endTime.textContent = `Вернуться в ${adjustedHour}:${minutes ‹ 10 ? ‘0’ : ‘’}${минут} ${am_pm}`;

Теперь, когда мы настроили время и функции отображения, нам нужно добавить функциональность к различным кнопкам и вводу.

Мы нацеливаем все наши элементы на атрибут «data-time» и прикрепляем прослушиватель событий «click», который вызывает функцию «startTimer». Код этой функции следующий:

константа секунд = +(this.dataset.time);
таймер (секунды);

Эта функция использует значение «дата-секунды» для каждого элемента кнопки и устанавливает его равным переменной «секунды». Поскольку «this.dataset.time» дает строку, мы используем знак «+», чтобы преобразовать строку в число, а затем передаем переменную в качестве аргумента функции «таймер». Если вы нажмете более одной кнопки до завершения, дисплей может быть перегружен различными таймерами. Чтобы решить эту проблему, вы должны очистить все интервалы в самом начале функции «таймер». Теперь мы делаем то же самое для нашего ввода.

Для ввода мы нацеливаем имя элемента формы вне документа — «document.customForm» — и присоединяем прослушиватель событий «отправить», который запускает анонимную функцию. Во-первых, вызывается «event.preventDefault», чтобы предотвратить перезагрузку страницы. Затем мы назначаем переменную «минуты», равную «this.minutes.value» — «это» — элемент формы, «минуты» — имя ввода, а «значение» — желаемое пользователем количество минут. Получив ввод пользователя, мы конвертируем его в секунды (минуты * 60) и передаем это значение в качестве аргумента функции «таймер». Последнее, что мы делаем, это запускаем this.reset, чтобы очистить ввод после ввода значения.

Все это должно дать вам работающий таймер обратного отсчета. Если вы хотите взглянуть на мой код, нажмите здесь, чтобы перейти на мою страницу GitHub.

Ударь крота —

Для последнего проекта мы создали классическую игру Whack-A-Mole. Поскольку я только что посмотрел фильм, я решил придать своей игре тему «Звездных войн». Игра присваивает случайной дыре класс, который поднимет штурмовика. У каждого штурмовика есть прослушиватель событий, чтобы определить, был ли он целью. Ударьте солдата, чтобы получить очко. Давайте пройдемся по коду.

HTML-код состоит из тега h1, элемента span для счета, кнопки для запуска игры и div-контейнера игры. Есть шесть отверстий. У каждой дыры есть div с классом «holehole#» и div внутри дырки для крота.

Единственное, что следует отметить в CSS, — это класс «.up», который изменяет верхнее положение крота со 100% на 0%.

В файле Javascript мы начинаем с нацеливания на дыры, табло и родинки. У нас есть три переменные, которые позже будут переназначены:

· lastHole, чтобы одна и та же дыра не появлялась дважды.

· Timeup, переменная флага для начала и окончания игры.

· Score, чтобы указать счет пользователя.

Первая функция — «randomTime», которая принимает минимальное и максимальное значения и возвращает случайное значение между этим интервалом. Я включил код этой функции здесь:

function randomTime(min, max) {
return Math.round(Math.random() * (max — min) + min);

Время связано со скоростью появления родинок.

Вторая функция — «randomHole», присваивает случайное число, связанное с количеством отверстий, и использует это число в качестве значения индекса для вызова конкретного крота. Здесь используется переменная lastHole, чтобы убедиться, что одна и та же дыра не вызывается дважды. Если последняя дыра равна текущей дыре, снова вызовите «randomHole».

Функция «подглядывание» включает в себя большую часть игровых функций. Он использует функцию «randomTime» и присваивает возвращаемое число константной переменной. Функция также использует функцию «randomHole», чтобы вернуть случайную дыру и присвоить ее собственной константной переменной (дырке). Код этой части функции приведен здесь:

const time = randomTime(1000, 1500);
константное отверстие = randomHole(holes);
hole.classList.add('вверх');

Когда у нас есть случайное отверстие, мы добавляем к элементу класс «вверх», чтобы вывести крота из его отверстия. Однако в какой-то момент кроту нужно вернуться в свою нору.

Мы используем setTimeout для вызова функции по прошествии определенного времени, которое в данном случае является значением переменной «time» в функции «peep». В функции setTimeout мы удалим класс «.up» и определим, истекло ли время в игре, если нет, снова запустим функцию «peep».

Следующая функция — это функция «startGame», которая сбрасывает табло на ноль, переменную флага «timeUp» на false и счет на ноль. Кроме того, эта функция вызывает функцию «пип» для запуска игры. Последнее, что делает функция, — это определяет продолжительность игры, используя функцию setTimeout и переменную timeup, установленную в значение true, когда время истекло. Последняя функция — это функция «bonk», которая определяет, наткнулся ли пользователь на крота.

Функция «bonk» будет включать прослушиватель событий, прикрепленный к каждой родинке, и передает «событие» в качестве аргумента. Первая строка — это условное выражение, которое определяет легитимность клика с использованием метода «isTrusted» для объекта «событие». Если это законный клик, то оценка будет увеличена на единицу. Отверстие, которое было нажато, будет иметь удаленный класс «.up» — опускание крота обратно в отверстие — счет будет увеличен на единицу, и на табло будет обновлен новый счет.

Это должно сделать это для последнего вызова. Проверьте мой файл на GitHub для этого проекта здесь.

Это должно сделать это для всех 30 проектов. Если вы решаете задачи самостоятельно, то я надеюсь, что эта статья помогла вам с любыми проблемами, с которыми вы столкнулись. Чтобы увидеть некоторые из этих функций в действии, посетите мой веб-сайт MurphsCode.com.