Web.Study

Web.Study

Знакомим новичков со Вселенной Front-end Еще мы обитаем в телеграме, там нас удобнее читать – https://t.me/frontendforbegginers
На Пикабу
654 рейтинг 53 подписчика 8 подписок 40 постов 9 в горячем
12

Мам, сейчас так модно. Добавляем темную тему на страницу с помощью CSS

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


Сегодня мы добавим на страницу переключатель тёмной и светлой темы с помощью CSS.


Не только про CSS, но и про другие штуки из области Front-end мы рассказываем тут

Мам, сейчас так модно. Добавляем темную тему на страницу с помощью CSS Программирование, IT, Программист, CSS, Frontend, Web-программирование, Веб-дизайн, Веб-разработка, Длиннопост

Автопереключение тёмной темы



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


@Media screen and (prefers-color-scheme: dark) {}


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

Мам, сейчас так модно. Добавляем темную тему на страницу с помощью CSS Программирование, IT, Программист, CSS, Frontend, Web-программирование, Веб-дизайн, Веб-разработка, Длиннопост

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


Посмотреть на автопереключение темы на странице проекта.



Ручное переключение темы


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


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



Настраиваем стили


Единственное, что нам нужно добавить в стили — это два класса: для светлой и тёмной темы:

Мам, сейчас так модно. Добавляем темную тему на страницу с помощью CSS Программирование, IT, Программист, CSS, Frontend, Web-программирование, Веб-дизайн, Веб-разработка, Длиннопост

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


Внешне страница никак не поменяется — мы ещё не применили эти стили. Чтобы это сделать, надо поработать с остальными элементами, например добавить id к тегу <body> — по нему мы будем обращаться к содержимому всей страницы:

<body id="main">

Добавляем переключатель


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

<p id="select" onclick="darkLight()" style="cursor: help;">Включить тёмную тему</p>

Вот что здесь происходит:


<p id="select» ← указываем id переключателя, чтобы потом получить доступ к нему из скрипта;


onclick="darkLight ()» ← говорим, что должно произойти при нажатии: вызываем функцию darkLight ();


style="cursor: help;»> ← меняем внешний вид курсора при наведении на переключатель;


Включить тёмную тему</p> ← текст надписи.


Переключатель появился на странице, но пока ничего не переключает. Исправим это в скрипте.

Мам, сейчас так модно. Добавляем темную тему на страницу с помощью CSS Программирование, IT, Программист, CSS, Frontend, Web-программирование, Веб-дизайн, Веб-разработка, Длиннопост

Пишем скрипт


Мы указали в свойствах переключателя, что при нажатии нужно выполнить функцию darkLight () — значит, нам нужно добавить её в рабочий скрипт.


Чтобы не зависеть от работы других скриптов и не лезть в их код, сделаем новый js-файл dark.js и положим в него такой код:

Мам, сейчас так модно. Добавляем темную тему на страницу с помощью CSS Программирование, IT, Программист, CSS, Frontend, Web-программирование, Веб-дизайн, Веб-разработка, Длиннопост

Последнее, что осталось сделать, — подключить скрипт в конце HTML-страницы:


<script type="text/javascript" src="dark.js"></script>


Теперь у нас появилась поддержка тёмной темы с моментальным переключением:

Мам, сейчас так модно. Добавляем темную тему на страницу с помощью CSS Программирование, IT, Программист, CSS, Frontend, Web-программирование, Веб-дизайн, Веб-разработка, Длиннопост

Посмотреть на работу переключателя на странице проекта.



Что дальше


Этот способ работает только на одной странице, и после перезагрузки тему нужно переключать заново. В следующий раз сделаем апгрейд — научим сайт запоминать настройки и применять их ко всему сайту. А ещё подружим автопереключение с надписью на переключателе.

Показать полностью 6
16

Как поймать баг в коде: отладка в браузере. Вместо тысячи console.log()

Что такое отладка


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

Как поймать баг в коде: отладка в браузере. Вместо тысячи console.log() Программирование, IT, Инструкция, Баг, Frontend, Web, Длиннопост

Варварская отладка


Самый примитивный вариант отладки — добавить в код на JavaScript метод console.log (), поместив в скобки нужные данные для отладки. Console.log () — это просто способ вывести в консоль какой-нибудь текст.


Например, внутри функции можно сказать: console.log (‘Вызвана такая-то функция’) — и в нужный момент мы увидим, что функция вызвалась (или нет).


Минус этого подхода в том, что в коде появляется много отладочного мусора. А ещё, если мы не предусмотрели логирование для какой-то функции, то мы не поймаем в ней ошибку.


К счастью, помимо console.log () человечество изобрело много удобных инструментов отладки.



Что нужно для отладки

Для несложных проектов на JavaScript проще всего использовать встроенный отладчик в браузере Google Chrome. Единственное ограничение — он работает только с файлами скриптов, а не со встроенным в страницу кодом. Это значит, что если код скрипта находится внутри HTML-файла внутри тега <script>, то отладка не сработает.


Чтобы открыть панель отладки в Chrome, нажимаем ⌘+⌥+I и переходим на вкладку Sources (Источники):

Как поймать баг в коде: отладка в браузере. Вместо тысячи console.log() Программирование, IT, Инструкция, Баг, Frontend, Web, Длиннопост

Открываем скрипт


Допустим, мы хотим посмотреть, как работает какой-либо скрипт.


Всё, что у нас есть, — это код. Чтобы мы смогли его отладить, его нужно положить в отдельный файл скрипта, присоединить к HTML-документу и запустить в браузере.


Открываем любой текстовый редактор, например Sublime Text, вставляем код скрипта и сохраняем файл как temp.js. Имя может быть любым, а после точки всегда должно стоять js — так браузер поймёт, что перед нами скрипт.


После этого в новом файле вставляем шаблон пустой HTML-страницы и подключаем наш скрипт — добавляем в раздел <body> такую строку:

<script type="text/javascript" src="temp.js"></script>
Получиться должно что-то вроде такого:

Как поймать баг в коде: отладка в браузере. Вместо тысячи console.log() Программирование, IT, Инструкция, Баг, Frontend, Web, Длиннопост

Сохраняем этот код как HTML-файл, например index.html, и кладём в ту же папку, что и скрипт. Теперь заходим в папку и дважды щёлкаем по HTML-файлу, чтобы открыть эту страницу в браузере:

Как поймать баг в коде: отладка в браузере. Вместо тысячи console.log() Программирование, IT, Инструкция, Баг, Frontend, Web, Длиннопост

На странице ничего нет, но нам нужна не страница, а скрипт, поэтому находим слева наш файл temp.js и нажимаем на него — откроется код скрипта. Теперь можно начинать отладку:

Как поймать баг в коде: отладка в браузере. Вместо тысячи console.log() Программирование, IT, Инструкция, Баг, Frontend, Web, Длиннопост

Добавляем точки остановки


Точка остановки — это место, в котором наш скрипт должен остановиться и ждать дальнейших действий программиста. Их ещё называют брейкпоинты, от английского breakpoint — точка, где всё останавливается.


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


Брейкпоинт нужен для того, чтобы выполнить скрипт по шагам, начиная с первой команды. Чтобы его установить, нажимаем на номер строки с первой командой — в нашем случае это строка 2:

Как поймать баг в коде: отладка в браузере. Вместо тысячи console.log() Программирование, IT, Инструкция, Баг, Frontend, Web, Длиннопост

Обновим страницу и увидим, что скрипт начал работу и остановился. Но он остановился не на второй строке, а на шестой — всё потому, что это первая строка в скрипте, где происходит какое-то действие. Дело в том, что просто объявление новых переменных не влияет на работу скрипта, поэтому он ищет первую команду с действием. В нашем случае — это цикл for:

Как поймать баг в коде: отладка в браузере. Вместо тысячи console.log() Программирование, IT, Инструкция, Баг, Frontend, Web, Длиннопост

Пошаговая отладка


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

Как поймать баг в коде: отладка в браузере. Вместо тысячи console.log() Программирование, IT, Инструкция, Баг, Frontend, Web, Длиннопост

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

Как поймать баг в коде: отладка в браузере. Вместо тысячи console.log() Программирование, IT, Инструкция, Баг, Frontend, Web, Длиннопост

Добавляем переменные для отслеживания


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


Чтобы добавить переменную и видеть её значение во время выполнения, в панели отладки в разделе Watch нажимаем плюсик, вводим имя переменной, выбираем её из списка и нажимаем энтер:

Как поймать баг в коде: отладка в браузере. Вместо тысячи console.log() Программирование, IT, Инструкция, Баг, Frontend, Web, Длиннопост

Теперь видно, что на этом шаге значение переменной a равно нулю:

Как поймать баг в коде: отладка в браузере. Вместо тысячи console.log() Программирование, IT, Инструкция, Баг, Frontend, Web, Длиннопост

Точно так же добавим остальные переменные: i, b, c. Так мы увидим, что первые два цикла только начались, а внутренний прошёл уже три итерации:

Как поймать баг в коде: отладка в браузере. Вместо тысячи console.log() Программирование, IT, Инструкция, Баг, Frontend, Web, Длиннопост

Так, нажимая постоянно F9, мы прогоним весь скрипт до конца и посмотрим, при каких значениях какие условия выполняются и как находится решение:

Как поймать баг в коде: отладка в браузере. Вместо тысячи console.log() Программирование, IT, Инструкция, Баг, Frontend, Web, Длиннопост

Но у такого подхода есть минус — если вложенных циклов много или скрипт очень большой, то на пошаговое выполнение уйдёт много времени. Чтобы не перебирать всё вручную, ставят дополнительные брейкпойнты в нужных местах.



Отладка брейкпойнтами


Допустим, нам важно понять, в какой момент скрипт находит и выдаёт решение. Глядя в код, мы понимаем, что как только скрипт дошёл до команды console.log () — он нашёл очередное решение. Это значит, что мы можем поставить брейкпоинт только на эту строчку и не прогонять вручную весь скрипт: он сам остановится, когда дойдёт до неё, а мы сможем посмотреть значения переменных в этот момент.


Для этого:

1. Нажимаем снова на строку 2 и убираем предыдущую точку остановки.

2. Ставим брейкпоинт на строку 20 — там, где происходит вывод решения в консоль.

3. Нажимаем F8.

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

Как поймать баг в коде: отладка в браузере. Вместо тысячи console.log() Программирование, IT, Инструкция, Баг, Frontend, Web, Длиннопост

Таких точек остановки можно поставить сколько угодно и в любой момент — на каждой из них отладчик остановится и покажет текущее состояние скрипта.



Зачем это всё


Отладка нужна, чтобы найти ошибки в программе. Если мы видим, что на очередном шаге в переменной находится не то, что мы ожидали увидеть, значит, что-то в коде идёт не так. Мы ставим брейкпоинт на начало нужных команд, запускаем отладку и находим команду, которая приводит к ошибке.


В следующей статье мы покажем на примере с реальным кодом, как отладка помогает находить и исправлять такие ошибки. Подпишитесь, на наш телеграм, чтобы не пропустить это – https://t.me/havaevau_webstudy

Показать полностью 13
23

4 редких API, которые встречаются в дикой природе JavaScript

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


Наш канал для новичков во Front-end

4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост

Beacon API


Beacon API позволяет отправлять на сервер асинхронные и неблокирующие запросы (методом POST), которые гарантированно завершаются до выгрузки страницы, в отличие от XMLHttpRequest или Fetch API.


Одним из основных вариантов использования Beacon API является логгирование активности пользователей или отправка аналитических данных на сервер.


Раньше для этого приходилось прибегать к таким уловкам, как обработка событий unload или beforeunload глобального объекта Window с помощью синхронного XMLHttpRequest, например:


const someData = {
a: 1,
b: 2,
};
// страница будет выгружена только после отправки данного запроса
window.addEventListener("beforeunload", () => {
const xhr = new XMLHttpRequest(); 
xhr.open("POST", "https://example.com/beacon");
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
const params = new URLSearchParams(Object.entries(someData)); xhr.send(params); 
});


Интерфейс


Beacon API расширяет свойство navigator методом sendBeacon, который имеет следующую сигнатуру:

navigator.sendBeacon(url: string | URL, data?: BodyInit | null)

- url — адрес сервера;

- data — опциональные данные для отправки, которые могут быть строкой, объектом, ArrayBuffer, Blob, DataView, FormData, TypedArray или URLSearchParams.


sendBeacon возвращает логическое значение (true или false) — индикатор постановки data в очередь для передачи.


Пример использования


Создаем шаблон проекта с помощью Yarn и Vite на чистом JavaScript:

# rare-web-apis - название проекта
# --template vanilla - используемый шаблон
yarn create vite rare-web-apis --template vanilla

Переходим в созданную директорию, устанавливаем зависимости и запускаем сервер для разработки:

cd rare-web-apis
yarn
yarn dev

Определяем в файле main.js следующий обработчик:

4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост

Событие visibilitychange объекта document (подробнее о нем можно почитать по ссылке, приведенной в начале статьи) является более надежным способом определения состояния видимости страницы, чем события unload или beforeunload. В обработчике при скрытии страницы, например, при переключении вкладки или сворачивании страницы, с помощью sendBeacon по адресу https://example.com/beacon отправляются некоторые данные в форме URLSearchParams.


Результат переключения вкладки:

4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост
4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост

Поддержка — 96.8%.



Clipboard API



Clipboard API позволяет выполнять асинхронные операции записи/чтения текстовых и других данных в/из системного буфера обмена, а также обрабатывать события copy, cut и paste (копирование, вырезка и вставка) буфера.

По причинам безопасности Clipboard API доступен только при условии, что:


- страница обслуживается по протоколу https или localhost;

- страница находится в активной вкладке браузера (не находится в фоновом режиме);

- операции записи/чтения инициализируются пользователем (например, с помощью нажатия кнопки).


Разрешение clipboard-write для записи данных предоставляется активной странице автоматически, а разрешение clipboard-read для чтения данных запрашивается у пользователя с помощью Permissions API.


Раньше для работы с содержимым редактируемой области использовался метод document.execCommand. Например, вот как выполнялась запись текста:

4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост

Интерфейс


Clipboard API расширяет свойство navigator интерфейсом Clipboard, экземпляры которого предоставляют следующие методы для работы с буфером:


- writeText(text: string) — для записи текста, принимает строку;

- readText() — для чтения текста, возвращает строку;

- write(data: ClipboardItem[]) — для записи данных, принимает массив объектов ClipboardItem (см. ниже);

- read() — для чтения данных, возвращает массив объектов ClipboardItem.


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


ClipboardItem — это интерфейс, предназначенный для работы с нетекстовыми данными, который имеет следующую сигнатуру:

new ClipboardItem(
items: Record<string, string | Blob | PromiseLike<string | Blob>>,
options?: ClipboardItemOptions
)

- items — данные для записи в форме объектов, ключами которых являются MIME-типы, а значениями — строки, Blob или промисы, разрешающиеся строками или Blob;

- options — опциональные настройки (точнее, одна настройка — presentationStyle).


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


Что касается событий copy, cut и paste, то их обработка обычно выполняется через свойство clipboardData события ClipboardEvent, которое содержит объект DataTransfer, предоставляющий следующие методы:


- setData(format: string, data: string) — для записи данных;

- getData(format: string) — для чтения данных;

- clearData() — для удаления данных и др.

Пример использования


Начнем с записи и чтения текста. Редактируем файл index.html следующим образом:

4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост

Получаем ссылки на DOM-элементы:

4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост

Определяем функцию копирования текста:


async function copyText() {
let textToCopy; 
// получаем выделение
const selectedText = getSelection().toString().trim(); 
// текстом для копирования является либо выделенный текст, либо содержимое `copyBox`
selectedText
? (textToCopy = selectedText)
: (textToCopy = copyBox.textContent.trim()); 
// если текст отсутствует
if (!textToCopy) {
logBox.textContent = "No text to copy"; 
return; 
}
try {
// записываем текст в буфер
await navigator.clipboard.writeText(textToCopy); 
logBox.textContent = "Copy success"; 
} catch (e) {
console.error(e); 
logBox.textContent = "Copy error"; 
}
}

Определяем функцию для вставки текста:

4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост

Наконец, регистрируем соответствующие обработчики:

copyBtn.addEventListener("click", copyText); 
pasteBtn.addEventListener("click", pasteText);

Обратите внимание: при первой вставке текста браузер запрашивает разрешение на чтение буфера. При отказе в разрешении выбрасывается исключение DOMException: Read permission denied.


Записать текстовые данные с помощью ClipboardItem можно следующим образом:

4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост

Обратите внимание: несмотря на то, что значением объекта ClipboardItem может быть строка (new ClipboardItem({ [type]: text })), при записи такого объекта в буфер выбрасывается исключение DOMException: Invalid Blob types.


Также обратите внимание, что при программной записи данных в случае, когда страница находится в фоновом режиме, выбрасывается исключение DOMException: Document is not focused.


Для извлечения данных из ClipboardItem используется метод getType:

const blob = await item.getType(type); 
const text = await blob.text(); 
console.log(text); // Text to copy

Добавим возможность копирования и вставки изображения, хранящегося на сервере.


Добавляем кнопки в index.html:

<div>
<button id="copy-img-btn">Copy remote image</button>
<button id="paste-img-btn">Paste remote image</button>
</div>

Определяем тип и функцию для копирования изображения:


const IMG_TYPE = "image/png";
async function copyRemoteImg() {
try {
const response = await fetch(
"https://images.unsplash.com/photo-1529788295308-1eace6f67388..."
);

// см. ниже
const blob = new Blob([await response.blob()], { type: IMG_TYPE });

// создаем элемент копирования

const item = new ClipboardItem({ [blob.type]: blob });
// записываем его в буфер
await navigator.clipboard.write([item]);

logBox.textContent = "Copy image success";
} catch (e) {
console.error(e);
logBox.textContent = "Copy image error";
}
}

Не уверен насчет других браузеров, но в Chrome наблюдается следующее:


- при преобразовании изображения из тела ответа в Blob с помощью response.blob() дефолтным типом становится image/jpeg (независимо от типа запрашиваемого изображения);

- при попытке записи такого Blob в буфер выбрасывается исключение DOMException: Type image/jpeg not supported on write.


Поэтому приходится выполнять двойное преобразование с помощью new Blob([await response.blob()], { type: IMG_TYPE });.


Определяем функцию для чтения данных из буфера и вставки изображения:

4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост

Итерация по item.types является безопасной, в отличие от прямого обращения к item.getType() — при отсутствии типа выбрасывается исключение DOMException: Failed to execute 'getType' on 'ClipboardItem': The type was not found.


Регистрируем соответствующие обработчики:

copyImgBtn.addEventListener("click", copyRemoteImg); pasteImgBtn.addEventListener("click", pasteRemoteImg);

Реализуем модификацию копируемых и вставляемых данных.


Редактируем index.html:


<textarea cols="30" rows="10" id="text-area">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Libero, labore.</textarea>

Определяем функцию модификации копируемых данных:

4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост

Данная функция добавляет к копируемому тексту строку copied from MySite.com.


Определяем функцию модификации добавляемых данных:

4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост

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


Обратите внимание, что в обоих случаях отключается стандартная обработка события браузером с помощью e.preventDefault().


Регистрируем соответствующие обработчики:

textArea.addEventListener("copy", onCopy); textArea.addEventListener("paste", onPaste);

Поддержка — 95.08%.



Notifications API


Notifications API позволяет отображать системные уведомления. Особенность этих уведомлений состоит в том, что они находятся вне контекста окна браузера, поэтому могут отображаться даже если пользователь сменил вкладку или свернул окно. Данный интерфейс разработан таким образом, что совместим со встроенными механизмами уведомлений на большинстве платформ.


Интерфейс


Для запроса разрешения на показ уведомлений используется метод Notification.requestPermission. Данный метод возвращает промис, который разрешается или отклоняется со статусом разрешения. Статус разрешения содержится в свойстве Notification.permission и может иметь одно из трех значений:


- default — запрос на разрешение не выполнялся, уведомления не отображаются;

- granted — пользователь предоставил разрешение, уведомления отображаются;

- denied — пользователь отклонил запрос, уведомления не отображаются.


Для создания уведомления используется конструктор Notification, который имеет следующую сигнатуру:

new Notification(title: string, options?: NotificationOptions | undefined)

- title: string — заголовок уведомления;

- options — опциональный объект с настройками, такими как:

- body: string — тело уведомления;

- icon: string — ссылка на иконку;

- tag: string — тег, используемый для идентификации уведомления. Тег позволяет обновлять уведомления без их отображения, что может быть полезным при большом количестве уведомлений;

- image: string — ссылка на изображение;

- data: any — данные, ассоциированные с уведомлением и др.


Для закрытия уведомления используется метод notification.close.


Notifications API позволяет обрабатывать следующие события:


- show — отображение уведомления;

- close — закрытие уведомления;

- click — нажатие на уведомление;

- error.


Пример использования


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


Определяем в index.html кнопку для запроса разрешения на показ уведомлений:

<button id="notification-btn">Enable notifications</button>

Регистрируем соответствующий обработчик в main.js:

notificationBtn.addEventListener("click", () => { Notification.requestPermission();
});
Определяем переменные для уведомления и идентификатора таймера, а также функцию для создания уведомления:
4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост

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


Расширяем обработку изменения состояния видимости страницы:

4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост

Включаем уведомления:

4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост

Переключаем вкладку:

4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост

При клике по уведомлению на странице приложения появляется сообщение Notification clicked.


Обратите внимание: при нахождении в другой вкладке уведомление уничтожается через 3 сек, а при возвращении в приложение — сразу.


Поддержка оставляет желать лучшего — 79.86%.



Performance API


Performance API позволяет измерять задержку в приложении на стороне клиента. Интерфейсы Performance (интерфейсы производительности) считаются высокоточными (high resolution), поскольку имеют точность, равную тысячным миллисекунды (точность зависит от ограничений аппаратного или программного обеспечения). Данные интерфейсы используются для вычисления частоты кадров (например, в анимации) и бенчмаркинге (например, для измерения времени загрузки ресурса).


Поскольку системные часы (system clock) платформы подвергаются различным корректировкам (таким как коррекция времени по NTP), интерфейсы Performance поддерживают монотонные часы (monotonic clock), т.е. время, которое все время увеличивается. Для этого Performance API определяет тип DOMHighResTimeStamp вместо использования интерфейса Date.now().


DOMHighResTimeStamp представляет высокоточную отметку времени (point in time). Данный тип является double и используется интерфейсами производительности. Значение DOMHighResTimeStamp может быть дискретной отметкой времени или разницей между двумя такими отметками.


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


Интерфейс


Основным методом, предоставляемым Performance API, является метод now, который возвращает DOMHighResTimeStamp, значение которого зависит от времени создания контекста браузера или воркера (worker).

Кроме этого, рассматриваемый интерфейс содержит два основных свойства:


- timing — возвращает объект PerformanceTiming, содержащий такую информацию, как время начала навигации, время начала и завершения перенаправлений, время начала и завершения ответов и т.д.;

- navigation — возвращает объект PerformanceNavigation, представляющий тип навигации, происходящей в текущем контексте браузера, такой как переход к странице из истории, по ссылке и т.п.


Пример использования


В качестве примера реализуем функцию для измерения времени выполнения другой функции.


Редактируем main.js:

4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост

Определяем функцию вычисления факториала числа и измеряем время ее выполнения:

const getFactorial = (n) => (n <= 1 ? 1 : n * getFactorial(n - 1)); howLong(getFactorial)(12);

Определяем функцию получения данных из сети и измеряем время ее выполнения:

const fetchSomething = (url) => fetch(url).then((r) => r.json()); howLong(fetchSomething)("https://jsonplaceholder.typicode.com/users?_limit=10");

Результат:

4 редких API, которые встречаются в дикой природе JavaScript Программирование, IT, Javascript, API, Frontend, Программист, Длиннопост

Поддержка — 97.17%.



Иии...


На этом все, надеюсь ты узнал что-то новое и применишь это на практике. Иначе зачем я писал этот и прошлый пост

Показать полностью 17
24

4 малоизвестных, но не маловажных API для Javascript

Недавно я копался на хабре и нашел подборку полезных API, которые при этом не мейнстримные. Решил поделиться ими с вами, чтобы вы их юзали на практике (а грех их не заюзать).


Наш канал для новичков во fron-end, где мы рассказываем не только о JS

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

Page Visibility API


Данный интерфейс позволяет определять, когда пользователь покидает страницу. Точнее, он вызывает событие при каждом изменении состояния видимости (visibility status) страницы, например, когда пользователь сворачивает/разворачивает окно, переходит на другую вкладку и т.д.


Раньше для этого приходилось прибегать к таким уловкам, как обработка событий blur и focus. Соответствующий код выглядел так:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

Приведенный код работает, но не совсем так, как ожидается. Поскольку событие blur вызывается, когда страница теряет фокус, оно может возникнуть, когда пользователь нажимает на поиск, диалоговое окно (alert), консоль или границу окна. События blur и focus сообщают нам о том, что страница активна, но не о том, видим или скрыт ее контент.


Случаи использования


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


• приостановка воспроизведения видео, каруселей изображений (автослайдеров) или анимации, когда пользователь покидает страницу;

• если на странице отображаются данные в реальном времени, нет смысла их обновлять, если пользователь покинул страницу;

• отправка аналитических данных о действиях пользователя.


Интерфейс


Page Visibility API предоставляет 2 свойства и одно событие для получения доступа к состоянию видимости страницы:


• document.hidden — доступное только для чтения глобальное свойство. Признано устаревшим. Если страница скрыта, возвращается true, иначе — false;

• document.visibilityState — обновленная версия document.hidden. Возвращает 4 возможных значения:
• visible — страница видима или, если быть точнее, страница не свернута и находится в текущей вкладке;

• hidden — страница скрыта;

• prerender — начальное состояние видимой страницы: предварительный рендеринг;

• unloaded — страница выгружена из памяти;

• visibilitychange — событие объекта document, возникающее при изменении visibilityState:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

Пример использования


В качестве примера рассмотрим приостановку видео и прекращение получения ресурсов из API, когда пользователь покидает страницу. Создаем шаблон проекта с помощью Vite и Yarn:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

Переходим в созданную директорию, устанавливаем зависимости и запускаем сервер для разработки:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

Приложение доступно по адресу http://localhost:3000.


Удаляем шаблонный код из файла main.js и добавляем элемент video в файле index.html:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

Возвращаемся к main.js. Добавляем обработчик события visibilitychange объекта document:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

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


Получаем ссылку на элемент video и управляем воспроизведением видео в зависимости от видимости страницы:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

Прим. пер.: приведенный код работать не будет: получаем ошибку Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.. Это объясняется тем, что вызов video.play() при изменении состояния видимости страницы на visible равносилен наличию у элемента video атрибута autoplay. Современные браузеры допускают автоматическое (без участия пользователя) воспроизведение видео только в режиме без звука. Соответственно, для того, чтобы код работал, как ожидается, элементу video необходимо добавить атрибут muted.


Когда пользователь покидает страницу, воспроизведение видео приостанавливается. Когда пользователь возвращается на страницу, воспроизведение видео продолжается.

Теперь рассмотрим пример прекращения выполнения запросов к API. Для этого напишем функцию, запрашивающую цитату из quotable.io. Добавляем в index.html элемент div для хранения цитаты:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

Определяем в main.js функцию для получения произвольной цитаты с помощью Fetch API:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

Приведенный код работает, но функция getQuote вызывается только один раз. Обернем ее в setInterval с интервалом в 10 секунд:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

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

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

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


Поддержка — 98.24%.


Web Share API


Web Share API предоставляет разработчикам доступ к встроенному механизму совместного использования (native sharing mechanism) операционной системы, что особенно актуально для мобильных телефонов. Данный интерфейс позволяет делиться текстом, ссылками и файлами без создания собственного механизма или использования сторонних решений.


Случаи использования


Web Share API позволяет делиться содержимым страницы в соцсетях или копировать его в буфер обмена пользователя.


Интерфейс


Web Share API предоставляет 2 метода:


• navigator.canShare(data): принимает данные для совместного использования и возвращает логическое значение — индикатор того, можно ли этими данными поделиться;

• navigator.share(data): возвращает промис, который разрешается в случае успешного шаринга (sharing) данных. Данный метод вызывает нативный механизм и принимает данные для шаринга. Обратите внимание: этот метод может вызываться только в ответ на действие пользователя (нажатие кнопки, переход по ссылке и т.п.) (требуется кратковременная активация). data — это объект со следующими свойствами:

• url — ссылка для шаринга;

• text — текст;

• title — заголовок;

• files — массив объектов File.



Пример использования


Возьмем последний пример и добавим возможность делиться цитатой. Добавляем соответствующую кнопку в index.html:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

В main.js получаем ссылку на эту кнопку и определяем функцию для шаринга данных:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

Нам также потребуется глобальная переменная для хранения содержимого текущей цитаты:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

Определяем обработчик нажатия кнопки:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

Обратите внимание: Web Share API работает только в безопасном окружении. Это означает, что страница должна обслуживаться по протоколу https или wss.


Поддержка — 89.82%.



Broadcast Channel API


Broadcast Channel API позволяет контекстам браузера (browser contexts) обмениваться данными друг с другом. К браузерным контекстам относятся такие элементы, как окно, вкладка, iframe и т.д. По причинам безопасности контексты, обменивающиеся данными, должны принадлежать одному источнику (same origin). Один источник означает одинаковый протокол, домен и порт.


Случаи использования


Broadcast Channel API обычно используется для синхронизации окон и вкладок браузера для улучшения пользовательского опыта или повышения безопасности. Он также может применяться для уведомления одного контекста о завершении процесса в другом контексте. Другие примеры:


• авторизация пользователя во всех вкладках;

• отображение загруженного ресурса во всех вкладках;

• запуск сервис-воркера для выполнения фоновой задачи.


Интерфейс


Broadcast Channel API предоставляет объект BroadcastChannel, позволяющий обмениваться сообщениями с другими контекстами. Конструктор этого объекта принимает единственный аргумент: строку — идентификатор канала (channel identifier):

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

BroadcastChannel предоставляет 2 метода:


• broadcastChannel.postMessage(message): позволяет отправлять сообщения всем подключенным контекстам. В качестве аргумента данный метод принимает любой тип данных:
4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

• broadcastChannel.close(): закрываем канал коммуникации, что позволяет браузеру выполнить сборку мусора.


При получении сообщения возникает событие message. Это событие содержит свойство data с отправленными данными, а также другие свойства, позволяющие идентифицировать отправителя, такие как origin, lastEventId, source и ports:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

Пример использования


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

Создаем директорию new-context в корне проекта. Создаем в ней файл index.html следующего содержания:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

Создаем файл new-context/main.js.


Получаем ссылку на div и создаем новый канал коммуникации:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

Добавляем обработчик события message:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

Создаем канал в основном main.js и редактируем функцию getQuote:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

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


• в корне проекта создаем файл vite.config.js следующего содержания:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

• запускаем сервер для разработки с помощью команды yarn dev;

• открываем 2 вкладки:
• по адресу http://127.0.0.1:5173/index.html;

• по адресу http://127.0.0.1:5173/new-context/index.html.


Поддержка — 92.3%.



Internationalization API


Шпаргалка по Internationalization API


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


Предположим, что мы хотим отобразить на странице "10 ноября 2022 года" как "11/10/22". Эта дата в разных странах будет выглядеть по-разному:


• 11/10/22 или ММ/ДД/ГГ в США;

• 10/11/22 в Европе и Латинской Америке;

• 22/11/10 в Японии, Китае и Канаде.


Здесь на помощь приходит Internationalization API (или I18n). Данный интерфейс позволяет решить несколько групп задач, связанных с интернационализацией и локализацией, но в этой статье мы не будем погружаться в него слишком глубоко.


Интерфейс


Для определения страны пользователя в I18n используется идентификатор локали (или просто локаль) (locale identifier, locale). Локаль — это строка, представляющая страну, регион, диалект и другие характеристики. Если точнее, локаль — это строка, состоящая из подтегов (subtags), разделенных дефисом, например:


• zh — китайский (язык);

• zh-Hant — китайский (язык), традиционные иероглифы (сценарий — script);

• zh-Hang-TW — китайский (язык), традиционные иероглифы (сценарий), используемые на Тайване (регион).


Полный список подтегов можно найти в этом RFC.


I18n предоставляет объект Intl, который, в свою очередь, предоставляет несколько специальных конструкторов для работы с чувствительными к языку данными, наиболее интересными из которых являются следующие:


• Intl.DateTimeFormat — форматирование даты и времени;

• Intl.DisplayNames — форматирование названий языков, регионов и сценариев;

• Intl.Locale — генерация и манипуляция идентификаторами локалей;

• Intl.NumberFormat — форматирование чисел;

• Intl.RelativeTimeFormat — форматирование относительного времени (завтра, 2 дня назад и т.п.).


Пример использования


В качестве примера рассмотрим использование конструктора Intl.DateTimeFormat для форматирование свойства dateAdded цитат. Данный конструктор принимает 2 аргумента: строку locale для определения правил форматирование даты и объект options для кастомизации форматирования.


Прим. пер.: в качестве первого аргумента Intl.DateTimeFormat также принимает массив локалей. Например, для установки дефолтной локали пользователя в конструктор передается пустой массив ([]).


Объект, возвращаемый Intl.DateTimeFormat, предоставляет метод format, который принимает объект Date с датой для форматирования и объект options для кастомизации отображения форматированной даты:

4 малоизвестных, но не маловажных API для Javascript Программирование, IT, Javascript, API, Frontend, Длиннопост

Обратите внимание: мы установили настройку timeZone в значение UTC для того, чтобы при форматировании даты не учитывалось локальное время пользователя.


Определяем в main.js функцию для форматирования даты:

function formatDate(dateString) {
const date = new Date(dateString);
const dateTime = new Intl.DateTimeFormat([], { timeZone: "UTC" });
return dateTime.format(date);
}

Вызываем эту функцию внутри функции getQuote для форматирования свойства dateAdded:

const getQuote = async () => {
if (document.visibilityState !== "visible") return;
try {
// ...
const parsedQuote = `<q>${content}</q> <br> <p>- ${author}</p> <br> <p>Added on ${formatDate(
dateAdded
)}</p>`;
// ...
} catch (e) {
console.error(e); 
}
};

Поддержка — 97.74%.


Прим. пер.: на днях использовал Intl.DateTimeFormat для отображения даты и времени в коротком формате:

const getDateWithHoursAndMinutes = (date) => 
new Intl.DateTimeFormat([], {
dateStyle: "short",
timeStyle: "short",
}).format(date); 
console.log(getDateWithHoursAndMinutes(new Date())); // 23.09.2022, 21:30

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

Благодарю за внимание и happy coding!

Показать полностью 25

7 легких способов склонировать массив в JS

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


const cloneArr = (arr) => arr.slice(0);
const cloneArr = (arr) => arr.concat([]);
const cloneArr = (arr) => Array.from(arr);
const cloneArr = (arr) => arr.map((x) => x);
const cloneArr = (arr) => [...arr];
const cloneArr = (arr) => Array.from(arr);
const cloneArr = (arr) => JSON.parse(JSON.stringify(arr));

Удачи в экспериментах!


Наш канал

107

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

Как сделать сайт красивым на всех дисплеях?


Я перерыл половину Хабра в поисках САМОГО простого способа в минимум кода и кто ищет, тот всегда найдет. Под эту задачу подойдут следующие 58 байт:

58 байтов удовольствия. Выглядит красиво почти где угодно Программирование, IT, Полезное, CSS, Frontend, Web-программирование, Web, Веб-разработка, Веб-дизайн, Длиннопост

Давайте их разберём.


max-width: 38rem


Похоже, в большинстве браузеров по умолчанию используется размер шрифтов 16px, то есть 38rem — это 608px. Поддержка дисплеев разрешением минимум 600px кажется разумным

выбором.



padding: 2rem

Если ширина дисплея становится меньше 38rem, тогда благодаря этому отступу всё остаётся достаточно красивым до ширины примерно в 256px. Хотя это может казаться необязательным, на самом деле мы одним выстрелом убиваем двух зайцев: отступ также создаёт необходимое пространство сверху и снизу.



margin: auto


Это всё, что нужно для центрирования страницы, потому что main — это блочный элемент под семантическим html5.



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


Дополнение 1: после обсуждений я изменил значение padding на 1.5rem, чтобы улучшить компромисс между мобильными и десктопными дисплеями.

Дополнение 2: мне напомнили о ch unit, и он мне понравился! После этого я поменял значение на 70ch/2ch, что выглядит примерно так же, но на 2 байта меньше; только padding стал чуть меньше (это хорошо для мобильных).



100 байтов CSS, которые выглядят красиво где угодно (расширенная версия)


Это простой CSS, который будет хорошо выглядеть на большинстве дисплеев:

58 байтов удовольствия. Выглядит красиво почти где угодно Программирование, IT, Полезное, CSS, Frontend, Web-программирование, Web, Веб-разработка, Веб-дизайн, Длиннопост

Давайте его разберём.


max-width: 70ch


«удобный для чтения диапазон» обычно составляет в ширину 60-80 символов, и в CSS можно выразить это напрямую при помощи единицы измерения ch.



padding: 3em 1em


Если ширина дисплея оказывается меньше указанного выше max-width, то этот padding предотвращает растягивание текста на мобильных от края до края. Чтобы оставить пробелы сверху и снизу, мы используем 3em.



margin: auto


Это всё, что необходимо для центрирования страницы; применяется к html, потому что у сайта Дэна нет семантического тега </p>, который, скорее всего, существует на большинстве сайтов. То, что верхний тег центрирует себя относительно ничего, не совсем логично, но так делает большинство браузеров.



line-height: 1.75


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



font-size: 1.5em


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



Можно использовать :root вместо <html>, чтобы гарантировать наличие какого-нибудь селектора, но эта тонкость слишком сложна для меня и добавляет ещё один символ.



Ещё 100 необязательных байтов

58 байтов удовольствия. Выглядит красиво почти где угодно Программирование, IT, Полезное, CSS, Frontend, Web-программирование, Web, Веб-разработка, Веб-дизайн, Длиннопост

Пользуйтесь


И кстати, мы здесь рассказываем не только про CSS и банально, там нас будет удобнее читать :3

Показать полностью 3
15

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript

React — это библиотека JavaScript для создания пользовательского интерфейса.
Это официальное определение React. Но что если вы не знаете, что такое JavaScript? Что если вы не разработчик? Смогли бы вы тогда понять, что такое React?


Однозначно ДА. Именно поэтому я и написал эту статью на тему: Что такое React на самом деле? Что такое React.js (или ReactJS)? Для чего используется React? Почему React так популярен? Какие проблемы можно решить с его помощью?


Эта статья — введение в React для начинающих. И это первое, с чего стоит начать, прежде чем детально изучить React. Я объясню основные идеи React на пальцах (и с помощью картинок). Нет опыта работы с JavaScript? Не беда! Если у вас есть базовые знания HTML (например, HTML-тегов), эта статья должна вам понравиться.


Не нужно быть опытным разработчиком, чтобы понять суть React


Ниже я это вам докажу, но сначала краткое содержание поста:

1. Что такое DOM?

2. DOM API

3. Больше сложностей!

4. Основные идеи React

5. Компоненты

6. Декларативный интерфейс

7. Обновления реактивного DOM’а

8. Создаем свой первый React-компонент

9. Компоненты компонуемые

10. Компоненты можно использовать несколько раз

11. Компоненты независимы

12. Декларативное и императивное программирование

13. Заключение


Кстати, здесь мы рассказываем не только про React для новичков


Что такое DOM?

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

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

Ваш компьютер: Эй, что там такого классного в этом рандомном сайте learnreact.design?

Сервер: Подожди немного, мне надо кое-что проверить. Пип. Пип.

В ответе сервера вы в основном увидите три составляющие: HTML, CSS и JavaScript.


HTML перечисляет содержимое страницы и описывает её структуру. Сколько заголовков и абзацев? Какие изображения должен увидеть пользователь? Содержится ли эта кнопка и это текстовое поле в одном блоке?


Используя эту информацию, браузер создает то, что называется… DOM!


Так, стоп, DOM это… дерево? Да, это дерево! Как ни странно, многое в компьютере выглядит, как дерево. Давайте, как-то назовем нашего древесного друга… хм, как насчет Domo?


Домо — это, как натурщица в престижной художественной студии «Браузер». Его работа — позировать перед художником, который пишет портрет (или, возможно, миллионы портретов).

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

В реальной жизни DOM означает Document Object Model (Объектная модель документа). Это действительно модель — модель документа (также известная как страница). Она принимает позу. Браузер рисует портрет. Портреты — это то, что мы видим на странице: текстовые поля, абзацы, изображения и так далее. Работа разработчика похожа на работу режиссера, который говорит Domo, что надеть и какую позу принять. Все это определит, как в итоге будут выглядеть портреты.


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

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

DOM API


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


Помните: Для того, чтобы изменить то, что находится на странице, надо обновить DOM. Художник не сможет рисовать новые портреты, пока Domo не изменит свою позу.


Как заставить Domo принять новую позу?


Просто с ним поговорить. Он послушает. Интересно, что у ушей Domo есть название — DOM API.

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

Чтобы управлять DOM, разработчик пишет код на JavaScript, который взаимодействует с API DOM, и, в свою очередь, обновляет содержание страницы.



Больше сложностей!


Прямое общение с Domo было стандартным подходом к веб-разработке в течение многих лет, особенно когда контент был в основном статичным. Разработчик мог добавить интерактивность к статическим страницам, немного написав на JavaScript.


Но с появлением SPA (Single Page Application), таких как Gmail и Google Maps, пользователи стали ожидать гораздо большего. Вместо статических страниц им уже нужны интерактивные, быстрые и адаптивные приложения.


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


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

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

Основные идеи React


Позвольте представить вам супергероя, React:

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

С React разработчикам больше не нужно разговаривать напрямую с Domo. React действует как посредник между разработчиком и Domo. Он сглаживает углы при общении и ускоряет процесс создания портретов.


React также называют «ReactJS» или «React.js», но «React» — это официальное название.

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

React состоит из кода JavaScript. Он построен таким образом, что в большинстве случаев нет необходимости непосредственно работать с DOM API. Вместо этого мы пишем более простой код, в то время как React обрабатывает разговор с DOM за кадром.


У React есть несколько суперспособностей для решения постоянно усложняющихся задач веб-разработки:


• Компоненты

• Декларативный интерфейс

• Обновления реактивного DOM’а

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


Просто читайте дальше!



Компоненты


Компоненты — это главная особенность React. Основная идея состоит в следующем: разделяй и властвуй. Если задачу целиком трудно понять, мы разбиваем её на более мелкие задачи, решаем их по одной, а затем объединяем результаты.

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

Построение приложения на React почти всё построено на работе с компонентами: мы разбиваем приложение на компоненты, находим лучшие компоненты для работы, подгоняем их друг под друга, создаем новые компоненты из уже существующих и т.д.


Сегодня такие инструменты для веб-дизайна, как Framer и Figma (и символы в Sketch), также основаны на компонентах. Они очень похожи на React-компоненты, но последние более гибкие и мощные. Фактически, создатели инструментов дизайна вдохновлялись компонентами из разработки ПО. Как только компонент создан, мы можем создать несколько его копий. Мы можем использовать его для создания других компонентов. Если мы изменяем компонент, всё, что включает в себя этот компонент, будет обновляться автоматически.


У компонентов в React есть два важных свойства:


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

Компоненты независимы друг от друга. Если мы изменим код в одном месте, то другие компоненты не сломаются.


Если вам это кажется абстрактным, не волнуйтесь! Скоро я покажу вам несколько примеров и подробно объясню эти свойства.



Декларативный интерфейс


Декларативное vs. императивное программирование


Работая напрямую с DOM API, нам пришлось бы указывать, какой элемент изменять в нужное время, в нужном порядке. То есть пришлось бы подробно объяснять Domo, как расположить голову, руки и ноги для каждого портрета.

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

Звучит утомительно и чревато ошибками! Так почему бы просто не сказать Domo, что мы хотим, вместо того, чтобы объяснять, как позировать? На самом деле, именно так строится пользовательский интерфейс на React. Разработчик делает эскиз того, что он хочет, а React объясняет Domo, как позировать.

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

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

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

Говоря техническим языком, если код определяет, как мы хотим, чтобы это было сделано, это императивное программирование; если он определяет, что мы хотим, это декларативное программирование. При прямой работе с DOM API применяется императивное программирование, при работе с React — декларативное.


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



Виртуальный DOM


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


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

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

Эти эскизы называются виртуальный DOM. Виртуальным DOM’ом управлять гораздо быстрее, чем DOM’ом. Большую часть времени разработчики работают с виртуальным DOM’ом вместо того, чтобы напрямую работать с DOM’ом. React делает всю грязную работу по управлению таким медленным DOM’ом.

Обновления реактивного DOM’а


Что может быть круче? Представьте себе, что вы можете оставить плейсхолдер в эскизах, чтобы они представляли различные вариации одной и той же позы. Таким образом, если кто-то попросит портреты Domo в другой шапке, нам не нужно будет снова общаться с React. Мы можем просто сесть и позволить React изменить портрет за нас.

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

Шапка — это данные, определяющие динамическое содержимое пользовательского интерфейса. Нам просто нужно связать элементы интерфейса с их соответствующими данными. Когда данные меняются, React автоматически обновляет соответствующие элементы DOM для нас, то есть DOM «реагирует» на любые изменения соответствующих данных. Не нужно больше отслеживать данные. Не нужно беспокоиться о том, когда обновлять DOM. Он просто обновляется автоматически (с помощью React).


Именно так React и получил свое название. Интерфейс, построенный с помощью React, реагирует. Идея такого интерфейса значительно упрощает разработку интерфейса.



Создаем свой первый React-компонент


Теперь давайте рассмотрим на практике то, что мы теперь знаем, и создадим несколько реальных React-компонентов. Чтобы вам было легче понять, я опустил некоторые детали в коде (в частности, JavaScript). Цель состоит в том, чтобы вы поняли суть React, не погрязнув в синтаксисе JS. Если вам удобно читать код на JavaScript, можете проверить реальные исходные тексты.


Итак. Допустим, мы хотим помочь Domo создать онлайн-магазин шапок.



Компоненты компонуемые


Мы можем разделить интерфейс на несколько частей:


• Заголовок: заголовок сверху

• Главная: основная область контента

• Футер: футер в конце страницы

Эта декомпозиция в коде может выглядеть так:

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

Похоже на HTML, правда? Кроме тегов, которые начинаются с заглавной буквы: <Header>, <Content> и <Footer>. Это не стандартные теги HTML. Они кастомные.


Что это за кастомные теги? Как мы сообщим React, что заголовок состоит из тега заголовка, большого количества элементов списка и поисковой строки?


Давайте создадим компонент Header!
React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

Теперь компонент Header содержит два кастомных тега: <SearchBar> и <ShoppingCart>. Что внутри?

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост
React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

Помните первое важное свойство React-компонентов? Они компонуемые. Это означает, что мы можем использовать компоненты для создания других компонентов — именно это мы только что и сделали.


Теперь задание для вас:


Допустим, мы также хотим добавить SearchBar в футер. Что бы вы сделали? Отредактируйте код ниже:

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

Примечание:


• Убедитесь, что теги находятся внутри <footer>

• Прокрутите вверх, чтобы проверить код Header

• Попробуйте добавить другие теги

У вас получились две строки поиска? Значит вы поняли суть!



Компоненты можно использовать несколько раз


«Составной» означает способность создавать компонент, используя другие компоненты в качестве его составных частей. Это очень похоже на то, как всё происходит в природе, за исключением одного важного момента: когда мы используем компонент в другом компоненте в React, он все равно «прикрепляется» к оригинальному компоненту. Когда исходный компонент изменяется, все его производные меняются вместе с ним.


Измените ниже текст на кнопке в коде SearchBar:

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

Что-нибудь заметили? Панель SearchBar на обновленных Header и Footer. Так? Это очень похоже на то, как работают компоненты в таких программах дизайна, как Framer и Figma.


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



Компоненты независимы


Помните? React-компоненты независимы. Это значит, что если мы изменим один компонент, то другие компоненты (которые его не включают) всё равно будут вести себя так же, как и раньше.


При изменении компонента SearchBar меняются только заголовок и футер. Кажется, что это просто (и, возможно, даже очевидно). Но это фундаментальная идея в программной инженерии, и она прошла долгий путь, чтобы сделать разработку ПО управляемой.



Декларативное и императивное программирование


Теперь давайте перейдем к двум другим суперсилам React: декларативному интерфейсу и обновления реактивного DOM’а.


Уже выбрали шапку для Domo? Если нет, просто кликните по одной из шапок на рабочем столе. Шапка на голове Domo меняется, так?


В этом интерфейсе клик по элементу в таблице обновит данные «выбранной шапки». Так как мы связали DomoWithHat с «выбранной шапкой», шапка на Domo автоматически изменится. Помните? Обновления реактивного DOM’а.


Здесь вы видите код для компонента DomoWithHat.

React: наглядное пособие для начинающих. Создаем свой компонент без знаний JavaScript Программирование, IT, Javascript, Web-программирование, Frontend, Веб-разработка, React, Pikaweb, Длиннопост

В коде выше нам просто нужно определить, что мы хотим (Domo и шапка в div), и «подключить» данные («type = {hat}»). Когда данные элемента hat меняются (пользователь выбирает шапку), интерфейс обновляется автоматически. Нам не нужно беспокоиться о том, когда и как обновить DOM. Нам даже не нужно следить за данными. Нам нужно только набросать эскиз, т.е. код, приведенный выше. Вот они, две другие суперсилы React: декларативный пользовательский интерфейс и обновления реактивного DOM’а.



Заключение


Поздравляю! Вы закончили урок по React. Он был о том, зачем нам вообще нужен React. Вот три основных плюса, которые делают React таким мощным: компоненты, декларативный интерфейс и обновления реактивного DOM’а.


На самом деле, готов поспорить, что даже некоторые опытные разработчики React (например, я!) не очень хорошо понимают эти понятия.


А вы?

Показать полностью 20
Отличная работа, все прочитано!