Code Ready | Frontend
前往频道在 Telegram
Авторский канал по Frontend разработке. Ресурсы, гайды, задачи, шпаргалки. Информация ежедневно пополняется! Cотрудничество: @energy_c РКН: https://clck.ru/3NJCKs
显示更多📈 Telegram 频道 Code Ready | Frontend 的分析概览
频道 Code Ready | Frontend (@code_ready) 俄语 语言赛道中的 是活跃参与者。目前社区聚集了 21 545 名订阅者,在 技术与应用 类别中位列第 6 157,并在 俄罗斯 地区排名第 30 472 位。
📊 受众指标与增长动态
自 невідомо 创建以来,项目保持高速增长,吸引了 21 545 名订阅者。
根据 26 十月, 2026 的最新数据,频道保持稳定运转。过去 30 天订阅人数变化为 -42,过去 24 小时变化为 -20,整体触达仍然可观。
- 认证状态: 未认证
- 互动率 (ER): 平均受众互动率为 6.43%。内容发布后 24 小时内通常能获得 4.29% 的反应,占订阅者总量。
- 帖子覆盖: 每篇帖子平均可获得 1 386 次浏览,首日通常累积 925 次浏览。
- 互动与反馈: 受众积极参与,单帖平均反应数为 23。
- 主题关注点: 内容集中在 css, браузер, интерфейс, загрузка, api 等核心主题上。
📝 描述与内容策略
作者将该频道定位为表达主观观点的平台:
“Авторский канал по Frontend разработке.
Ресурсы, гайды, задачи, шпаргалки.
Информация ежедневно пополняется!
Cотрудничество: @energy_c
РКН: https://clck.ru/3NJCKs”
凭借高频更新(最新数据采集于 27 十月, 2026),频道始终保持新鲜度与高覆盖。分析显示受众积极互动,使其成为 技术与应用 类别中的关键影响点。
21 545
订阅者
-2024 小时
-667 天
-4230 天
帖子存档
21 545
Дедлайны горят, а твои глаза уже нет. Что делать, если ты за#бался и хочется просто залипать в телефоне?
И вроде понимаешь, что НАДО, но от этого еще больше сопротивление.
Если близкие думают, что ты зажрался, а тебе и самому от себя уже тошно, но как себя взбодрить – непонятно, советую посмотреть вот что: https://t.me/Manifestans
Ты 100% себя узнаешь, а значит 100% получишь пользу от того, что там увидишь!
Если ты еще не собрал пожитки и не ушел отшельником в лес – есть шанс тебя оживить и вернуть эмоции и интерес к жизни.
Кликай сюда и начинай приходить в себя.
21 545
Добавляем дополнительную информацию с помощью тега <small>!
Тег
<small> используется для отображения второстепенного текста, который имеет меньшее значение по сравнению с основным содержимым. Он подходит для информации, которая полезна пользователю, но не является частью основного сообщения.
Для чего <small> подойдёт идеально:
• пояснения;
• комментарии;
• дисклеймеры;
• предостережения;
• копирайт;
• информация о лицензии;
• прочая правовая информация.
Важно: <small> имеет семантическое значение, а не просто уменьшает размер текста. Для изменения визуального размера обычного текста лучше использовать CSS.
📣 Code Ready | #атрибут21 545
Symbol: как добавлять внутренние свойства объектов без конфликтов!
В JavaScript объекты часто используются разными частями приложения, библиотеками и компонентами одновременно. Иногда требуется добавить к существующему объекту дополнительные данные: состояние компонента, метаданные, кэш или внутренние флаги.
Добавление обычных свойств может привести к конфликтам. Если такое имя уже используется другим кодом, одно значение может случайно заменить другое.
const element = {
value: "button"
};
element.state = {
mounted: true
};
Если свойство state уже существует в объекте, новое значение перезапишет старое. В больших приложениях такие ситуации могут быть сложными для поиска, особенно когда объект расширяется несколькими независимыми модулями.
Для решения этой задачи существует Symbol — это примитивный тип данных, который создаёт уникальные ключи свойств объектов. Каждый созданный символ является уникальным, поэтому он не может случайно совпасть с обычным строковым свойством или другим символом.
const internalState = Symbol("internalState");
const component = {
value: "button",
[internalState]: {
mounted: true
}
};
console.log(component[internalState]);
// { mounted: true }
Теперь внутренние данные хранятся по уникальному ключу. Объект можно расширять дополнительным состоянием, не изменяя его публичную структуру.
Даже если другой код добавит свойство с похожим названием, конфликт не возникнет:
component.internalState = false;
console.log(component[internalState]);
// { mounted: true }
Symbol-свойства имеют ещё одну особенность: они не отображаются в большинстве стандартных способов перебора объектов. Например, Object.keys() возвращает только строковые ключи:
Object.keys(component);
// ["value"]
Это позволяет хранить дополнительные данные внутри объекта, не добавляя их в обычное представление объекта и его публичный API. При необходимости получить символьные свойства можно явно:
Object.getOwnPropertySymbols(component);
Такой подход часто используется в библиотеках и компонентах, которым необходимо хранить внутренние данные, связанные с объектом. Например, можно добавить метаданные компонента:
const meta = Symbol("meta");
function initComponent(component) {
component[meta] = {
id: crypto.randomUUID(),
createdAt: Date.now()
};
}
После этого объект получает внутреннюю информацию, но его внешний интерфейс остаётся неизменным:
component.id;
// undefined
component[meta].id;
// UUID
Кроме пользовательских символов, JavaScript содержит встроенные Symbol, которые позволяют изменять стандартное поведение объектов:
Symbol.iterator
Symbol.asyncIterator
Symbol.toPrimitive
Например, Symbol.iterator позволяет объекту поддерживать цикл for...of:
const collection = {
items: ["a", "b"],
[Symbol.iterator]() {
return this.items[Symbol.iterator]();
}
};
for (const item of collection) {
console.log(item);
}
Важно понимать: Symbol не является механизмом настоящей приватности. Символьные свойства можно найти через:
Object.getOwnPropertySymbols();
Reflect.ownKeys();
Основная задача Symbol — создавать уникальные ключи и безопасно расширять объекты без риска конфликтов имён. Для настоящей приватности в классах JavaScript используются #private fields.
🔥 Symbol — практический инструмент для создания библиотек, компонентов и больших frontend-систем, где требуется добавлять внутренние данные, сохраняя чистый публичный API объекта.
📣 Code Ready | #практика21 545
Издательский дом «Новые отраслевые медиа» собрал для вас лучшие каналы из сферы искусственного интеллекта и интернет-технологий, которые помогают своим подписчикам быть в курсе всех важных профессиональных новостей.
Здесь - всё про ключевых игроков отрасли, государственное регулирование, инсайды и кейсы от отраслевых лидеров.
✅Серверная - канал об индустрии дата-центров: технологиях, инфраструктуре, облачных решениях, энергоэффективности и применении ЦОД в ключевых отраслях экономики.
✅Робосфера - канал об индустрии робототехники: технологии и тренды. Промышленные и сервисные роботы, коботы, автоматизация, ИИ, машинное зрение, автономные системы.
✅AI для бизнеса - всё об AI-решениях для бизнеса: внедрение, автоматизация, корпоративный ИИ, агенты.
✅ТехноРитейл - канал о производстве и продаже бытовой техники и электроники в России: бренды, e-com, маркетинг, retail tech.
Подписывайтесь, и эти каналы смогут изменить вашу жизнь к лучшему!
Реклама. Харламов А.Е. ИНН 712803816807. erid: 2W5zFJNTBaZ
21 545
👩💻 Отключает валидацию формы. Зачем нам валидация формы браузером, когда у нас есть JS?
Атрибут
novalidate используется у тега <form> и отключает стандартную валидацию полей браузером при отправке формы.
По умолчанию браузер сам проверяет такие ограничения, как:
• обязательные поля (required);
• корректность email (type="email");
• формат данных (pattern);
• минимальные и максимальные значения (min, max).
После добавления novalidate эта проверка не выполняется, и отправка формы передаётся полностью под контроль JS или серверной логики. Важно: novalidate не отключает атрибуты в HTML, а только запрещает браузеру автоматически проверять их при отправке.
📣 Code Ready | #атрибут21 545
Passive Event Listeners: оптимизация обработки touch- и wheel-событий!
При обработке некоторых событий ввода браузеру необходимо понимать, может ли JavaScript-обработчик отменить стандартное поведение события.
Например, при взаимодействии с экраном пользователь ожидает мгновенной прокрутки страницы. Однако обработчик
touchmove может вызвать event.preventDefault() и заблокировать стандартный жест браузера. Если обработчик считается непассивным, браузеру может потребоваться дождаться завершения его выполнения, прежде чем начать или продолжить прокрутку. Обычный обработчик события:
window.addEventListener(
'touchmove',
event => {
const touch = event.touches[0];
console.log(
touch.clientX,
touch.clientY
);
},
{
passive: false
}
);
В этом случае браузер должен учитывать, что обработчик потенциально может вызвать preventDefault(). Поэтому прокрутка может быть отложена до завершения выполнения JavaScript-кода.
Чтобы явно указать, что обработчик не будет отменять стандартное поведение, используется параметр passive.
window.addEventListener(
'touchmove',
event => {
const touch = event.touches[0];
console.log(
touch.clientX,
touch.clientY
);
},
{
passive: true
}
);
Теперь браузер знает, что обработчик не вызовет preventDefault(), и может обрабатывать прокрутку без ожидания завершения JavaScript-кода.
Следует учитывать, что современные браузеры в некоторых случаях автоматически используют пассивный режим для обработчиков touchstart, touchmove, wheel и mousewheel, зарегистрированных на window, document или body. Конкретное поведение зависит от браузера, события и целевого элемента. Поэтому, если обработчик должен гарантированно вызывать preventDefault(), лучше явно указать:
{
passive: false
}
Событие scroll отличается тем, что возникает после изменения позиции прокрутки и не может быть отменено через preventDefault(). Поэтому использование passive для scroll не даёт преимуществ производительности. Например:
window.addEventListener(
'scroll',
() => {
const position = window.scrollY;
document.querySelector(
'.header'
).style.opacity = Math.min(
position / 500,
1
);
}
);
В данном примере при каждом вызове обработчика выполняется поиск элемента в DOM и изменяется его стиль. При высокой частоте событий это создаёт дополнительную нагрузку на основной поток.
В подобных случаях эффективнее заранее сохранить ссылку на элемент, сократить объём выполняемой работы и при необходимости использовать requestAnimationFrame или throttling.
const header = document.querySelector('.header');
let scheduled = false;
window.addEventListener('scroll', () => {
if (scheduled) {
return;
}
scheduled = true;
requestAnimationFrame(() => {
header.style.opacity = Math.min(
window.scrollY / 500,
1
);
scheduled = false;
});
});
debounce обычно применяют для действий, которые должны выполняться после завершения прокрутки, например для отправки аналитики или сохранения состояния интерфейса.
Также важно учитывать, что passive: true запрещает отмену стандартного поведения события. Вызов:
event.preventDefault();
Внутри пассивного обработчика не остановит стандартное поведение браузера и обычно приведёт к предупреждению в консоли.
window.addEventListener(
'touchmove',
event => {
event.preventDefault();
},
{
passive: true
}
);
passive: true целесообразно использовать, если обработчик только анализирует событие или обновляет интерфейс и ему не требуется вызывать preventDefault(). Если обработчик должен отменять стандартное поведение браузера, его нельзя делать пассивным.
🔥 Passive Event Listeners уменьшают задержки при обработке touch- и wheel-событий, поскольку браузеру не требуется ожидать возможного вызова preventDefault(). При этом они не устраняют проблемы, связанные с тяжёлыми JavaScript-обработчиками.
📣 Code Ready | #практика21 545
На Stepik вышла программа «DevOps с нуля: от Linux до Kubernetes»
Это комплексная программа из 5 практических курсов по ключевым технологиям DevOps: Linux, Git, Docker, GitLab CI/CD, Kubernetes
Вы последовательно пройдёте путь от работы в Linux и управления кодом через Git до контейнеризации приложений, настройки CI/CD-пайплайнов и развёртывания в Kubernetes.
Что вы изучите:
• работу с Linux и командной строкой • Git и контроль версий в реальных проектах • создание Docker-образов и запуск контейнеров • автоматизацию сборки, тестирования и деплоя в GitLab CI/CD • развёртывание и управление приложениями в Kubernetes • сети, хранилища, конфигурации и секреты • диагностику инфраструктуры и автоматизацию рутинных задач ... и многое другоеВсе знания закрепляются на практике с помощью заданий с автопроверкой. Материал подаётся последовательно и понятным языком: с примерами, схемами и демонстрациями. Во время обучения можно задавать вопросы по урокам и заданиям, получать обратную связь и помощь при возникновении сложностей. После прохождения программы вы получите сертификат, который можно добавить в резюме. Скидка 20% на 48 часов: по промокоду
READY20 стоимость всей программы составит 10 392 ₽.
Открыть программу на Stepik21 545
👩💻 Валидируем форму прямо в браузере. Без JavaScript, регистрации и смс!
Псевдоклассы
:valid и :invalid в CSS позволяют стилизовать поля формы в зависимости от результата встроенной HTML-валидации. Они работают с ограничениями вроде required, pattern, min, max, type="email" и другими.
Как это используется:
• :valid — поле заполнено корректно;
• :invalid — значение не прошло проверку;
• можно менять цвет рамки, фона или отображать состояние поля.
Это простой способ сделать форму более понятной для пользователя, не прибегая к JS.
📣 Code Ready | #свойство21 545
👨💻 Front-End Web Development Resources — большая подборка ресурсов по frontend-разработке!
Здесь собраны ресурсы по HTML, CSS, JavaScript, React, Angular, Vue.js, TypeScript, Git, UI/UX, адаптивной вёрстке, инструментам разработки и многим другим направлениям. Материалы подойдут как начинающим разработчикам, так и тем, кто уже работает и хочет расширить знания или быстро найти качественные источники по конкретной теме.
Оставляю ссылочку: GitHub 📱
📣 Code Ready | #репозиторий
21 545
Красивые переносы заголовков!
Часто последняя строка заголовка выглядит неаккуратно: одно-два коротких слова оказываются отдельно.
Обычно это исправляют вручную.
<h1>Новый<br>релиз CSS</h1>
Или вставляют , <wbr> и другие ручные переносы.
Теперь с этим может помочь сам браузер.
h1 {
text-wrap: balance;
}
Браузер старается более равномерно распределить текст между строками, чтобы заголовок выглядел аккуратнее. Лучше всего использовать это для коротких текстов: заголовков, подзаголовков, цитат и подписей.
Для длинных абзацев есть отдельный режим.
p {
text-wrap: pretty;
}
Он старается избегать неудачных переносов и слишком коротких последних строк. Если браузер его не поддерживает, текст просто будет переноситься как обычно.
🔥 text-wrap: balance и text-wrap: pretty позволяют заметно улучшить типографику буквально одной строкой CSS.
📣 Code Ready | #совет21 545
Ищут 10 человек, чтобы собирали чат-ботов по шаблону, как пазлы.
ЗП: от 5-9000₽ за вечер.
Занятость: 3-4 часа в день.
Опыт: не нужен.
Как мы работаем:
1. Ты проходишь обучение пару недель;
2. Берёшь реальный проект из моей базы;
3. Собираешь бота по проверенной формуле;
4. Наставник контролирует процесс;
5. Получаешь деньги и закрепляешь клиента.
Весь процесс занимает до 2х недель с нуля до первых денег на твою карту.
Даниил из Балашихи был военнослужащим — с июля 2024 года начал создавать чат-ботов для бизнеса и уже заработал 4 млн. рублей. А главное теперь у него больше свободного времени на семью, друзей и развлечения.
Да, ты не первый. 277 человек уже ведут постоянных клиентов по моей формуле. Ведь сайт со статистикой Wordstat показывает 10 786 запросов за месяц в поисковике от бизнеса на эту услугу.
Заказов валом. Срочно нужны твои руки и голова.
Чтобы быстро разобраться во всех нюансах — запускай бота
Там пошаговый план как стартануть и гайд по клиентам.
8 мест ещё свободно
21 545
🐱 8 шпаргалок для веб-разработчика — полезная подборка по HTML, CSS, JavaScript, React и Git!
На странице собрана крутая подборка из 8 полезных шпаргалок для веб-разработчиков. Здесь справочники по HTML, CSS, Grid Layout, Flexbox, JavaScript, React и Git с примерами кода, схемами и наглядными объяснениями. Полезно для frontend-разработчиков: можно быстро освежить знания по вёрстке, JavaScript и др. инструментам.
📌 Оставляю ссылочку: highload.tech
📣 Code Ready | #сайт
21 545
Range API — работа с диапазонами DOM и фрагментами документа!
Иногда нужно изменить не весь элемент целиком, а только конкретный участок внутри него: выделенный текст, часть DOM или место для вставки нового элемента. В таких случаях работы со строками недостаточно, нужно обращаться напрямую к структуре DOM.
Range позволяет описать участок документа между двумя точками в DOM и выполнять операции именно над этим фрагментом. Важно понимать разницу между Selection и Range.
Selection хранит то, что пользователь выделил мышкой, а Range описывает конкретные границы этого выделения и даёт инструменты для работы с ним. Например, получим текущее выделение пользователя:
const selection = window.getSelection();
if (selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
console.log(range.toString());
}
После получения Range мы можем работать с выбранным участком документа.
Метод toString() удобен, когда нужен только текст выделения. Но он возвращает обычную строку и не сохраняет HTML-структуру внутри этого фрагмента. Например, есть такой DOM:
<p>
Hello <strong>JavaScript</strong>
</p>
Если получить текст через:
range.toString();
мы получим: Hello JavaScript. Вся внутренняя структура будет потеряна, потому что результатом является просто строка.
Если нужно сохранить HTML-узлы внутри выделенного участка, используется cloneContents(). Этот метод создаёт копию выбранного фрагмента в виде DocumentFragment, сохраняя вложенные элементы:
const fragment = range.cloneContents();
document.body.appendChild(fragment);
Теперь вместе с текстом сохранится и структура:
<strong>JavaScript</strong>
Range можно не только получать из пользовательского выделения, но и создавать вручную. Например, можно программно выделить всё содержимое определённого элемента:
const element = document.querySelector('#editor');
const range = document.createRange();
range.selectNodeContents(element);
Теперь диапазон знает, какой фрагмент DOM нужно выделить.
Остаётся передать его в объект Selection, чтобы браузер показал это выделение пользователю:
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
После выполнения браузер выделит всё содержимое элемента. Но Range нужен не только для чтения выделений. С его помощью можно изменять DOM в конкретной позиции.
Например, заменить выделенный пользователем текст:
const range = window
.getSelection()
.getRangeAt(0);
const span = document.createElement('span');
span.textContent = 'Новый текст';
range.deleteContents();
range.insertNode(span);
Сначала deleteContents() удаляет выбранный фрагмент, а затем insertNode() вставляет новый элемент точно туда, где находился диапазон. Это особенно полезно в редакторах текста, где нужно сохранить структуру документа и позицию изменения.
Есть ещё один похожий метод — extractContents(). В отличие от cloneContents(), который создаёт копию, extractContents() забирает содержимое из DOM и удаляет его с текущего места:
const fragment = range.extractContents();
Полученный DocumentFragment можно затем вставить в другой участок документа. Range API используется внутри rich text редакторов, систем подсветки поиска, комментариев и любых интерфейсов, где требуется работать с отдельными частями документа.
🔥 Range API — инструмент для точной работы с фрагментами DOM: выделять, копировать, извлекать, удалять и заменять части документа без полной пересборки элемента.
📣 Code Ready | #практика21 545
41% кода уже пишет AI. Пора научиться использовать это в свою пользу
Пока одни всё ещё учат синтаксис, другие собирают рабочие продукты с помощью Claude Code и AI.
Хекслет проведёт бесплатный воркшоп, где за один вечер вы создадите собственного Telegram-бота для изучения английского.
На практике покажут, как:
• работать с Claude Code;
• подключать Gemini API;
• создавать AI, который сам генерирует уроки;
• запускать полноценные продукты без месяцев разработки.
В результате у вас останется готовый Telegram-бот, которого можно использовать самому или развивать дальше.
28 июля, 19:00 (мск)
Бесплатное участие.
Зарегистрироваться ->
#реклама
О рекламодателе
21 545
+4
📱 Осваиваем регулярные выражения!
Эта шпаргалка по ключевым приёмам работы с RegExp: квантификаторы, группы, классы символов, флаги и проверки начала или конца строки. Подойдёт для валидации данных, парсинга текста и оптимизации поиска.
📣 Code Ready | #шпора21 545
👩💻 Один тег чтобы обернуть секцию с поиском или фильтром!
Тег
<search> используется для обозначения секции страницы, которая содержит поиск или элементы фильтрации. Он помогает браузерам, поисковым системам и вспомогательным технологиям лучше понимать структуру страницы.
Использовать <search> можно для:
• формы поиска по сайту;
• фильтров каталога;
• панели поиска по таблицам или спискам;
• блока с настройками фильтрации.
Важно: тег относительно новый, поэтому поддержка в некоторых браузерах и вспомогательных технологиях пока развивается. При необходимости можно дополнительно использовать role="search".
📣 Code Ready | #атрибут21 545
Element.animate() — управление композицией анимаций в браузере!
CSS-анимации удобны, пока элемент имеет одно состояние. Но когда несколько эффектов должны управляться из JavaScript, Web Animations API даёт больше контроля.
Например, несколько анимаций одного элемента могут существовать одновременно:
const fade = element.animate(
[
{ opacity: 0 },
{ opacity: 1 }
],
{
duration: 300
}
);
const move = element.animate(
[
{ transform: 'translateY(20px)' },
{ transform: 'translateY(0)' }
],
{
duration: 300
}
);
Браузер создаёт отдельные Animation-объекты и объединяет их эффекты при расчёте итогового стиля элемента.
У каждой анимации есть собственное состояние:
console.log(fade.playState);
console.log(move.currentTime);
currentTime позволяет управлять прогрессом вручную:
fade.currentTime = 150;
Анимация сразу перейдёт примерно к середине выполнения. Это полезно для синхронизации анимаций с внешним состоянием, например с прогрессом загрузки:
animation.currentTime =
progress * animation.effect.getTiming().duration;
Также Web Animations API позволяет изменять параметры уже созданного эффекта:
animation.effect.updateTiming({
duration: 1000
});
При этом не нужно пересоздавать анимацию. Отдельно стоит учитывать композицию свойств. Если два эффекта изменяют один и тот же параметр:
element.animate(
[
{ transform: 'translateX(100px)' }
],
{
duration: 1000
}
);
element.animate(
[
{ transform: 'scale(1.2)' }
],
{
duration: 1000
}
);
Оба эффекта работают с одним CSS-свойством transform. Итоговое поведение зависит от правил композиции анимаций, поэтому параллельное изменение одного свойства может дать неожиданный результат.
Для сложных случаев можно управлять композицией через composite:
element.animate(
[
{
transform: 'translateX(100px)'
}
],
{
duration: 500,
composite: 'add'
}
);
В этом режиме новое значение добавляется к существующему, а не заменяет его.
🔥 Element.animate() — это не просто замена CSS keyframes. Web Animations API предоставляет полноценную модель управления анимациями: состояние, время выполнения, изменение параметров и правила композиции эффектов.
📣 Code Ready | #практика21 545
На Stepik запустили курс по вайбкодингу c Claude Code
Первым делом вы освоите базу Claude Code и научитесь проектировать полноценные приложения.
После этого перейдёте к более продвинутым инструментам и автоматизации:
➡️Разработаете собственные MCP-серверы и Claude Skills
➡️Автоматизируете разработку с помощью Agent Loops и хуков
➡️Освоите Claude Design, Cowork и Connectors
➡️Построите личную систему знаний на базе Obsidian + Claude Cowork
➡️Научитесь работать с таблицами при помощи Cowork
➡️Перестанете постоянно упираться в лимиты Claude
А в финале получите готовую дорожную карту, полезные лайфхаки и 7 практических способов обхода блокировок Claude Code в России.
🔥 В течении 48 часов действует скидка 25%
21 545
Наткнулся на необычную и очень интересную статью на Хабре: «PowerHTML»!
В этой статье:
• Показывается, как создать интерактивные презентации, которые работают полностью офлайн в одном HTML-файле без установки программ и регистрации;
• Разбираются возможности редактора: встроенные видео, анимации, таймеры, интерактивные элементы и др;
• Объясняется, как с помощью AI был создан полноценный инструмент, ориентированный на преподавателей, спикеров и всех, кто проводит презентации.
🔊 Продолжайте читать на Habr!
📣 Code Ready | #статья21 545
Intl.ListFormat: форматируем списки с учётом языка пользователя!
При разработке интерфейсов часто нужно вывести набор данных в виде обычного текста: участников команды, выбранные фильтры, категории товара или список доступных вариантов.
Самый простой вариант — использовать
join():
const users = [
'Alex',
'Maria',
'John'
];
users.join(', ');
Такой подход работает только для простого разделения элементов. Но он не знает правил конкретного языка. В английском между последними элементами используется and, в русском — и, а в других локалях могут быть свои правила форматирования.
Если приложение поддерживает несколько языков, обычно появляются ручные проверки:
if (locale === 'en') {
// добавить and
}
if (locale === 'ru') {
// добавить и
}
Поддерживать такую логику сложно, поэтому для подобных задач в JavaScript существует стандартный API Intl.ListFormat.
Создаём форматтер и передаём нужную локаль:
const formatter =
new Intl.ListFormat('ru');
formatter.format([
'JavaScript',
'TypeScript',
'Python'
]);
Результат: JavaScript, TypeScript и Python.
При изменении локали правила форматирования изменятся автоматически:
const formatter =
new Intl.ListFormat('en');
formatter.format([
'JavaScript',
'TypeScript',
'Python'
]);
Результат: JavaScript, TypeScript, and Python.
Intl.ListFormat использует встроенные правила локализации JavaScript, поэтому не нужно самостоятельно реализовывать союзы, разделители и особенности разных языков.
Кроме обычного перечисления можно форматировать варианты выбора. Например, когда пользователь выбирает один из способов оплаты:
const formatter =
new Intl.ListFormat(
'ru',
{
type: 'disjunction'
}
);
formatter.format([
'Карта',
'PayPal',
'Перевод'
]);
Результат: Карта, PayPal или Перевод.
По умолчанию используется conjunction — обычное перечисление через союз "и". Значение disjunction используется для альтернатив через "или".
Также важно понимать, что Intl.ListFormat не изменяет исходные данные. Он только создаёт новую строку:
const tags = [
'Frontend',
'Backend',
'DevOps'
];
const text =
new Intl.ListFormat('ru')
.format(tags);
Массив tags останется без изменений, что удобно при работе с состоянием приложения и неизменяемыми данными. В реальных проектах этот API полезен для отображения пользователей, тегов, фильтров, категорий и любых списков, которые должны выглядеть естественно для пользователей из разных стран.
🔥 Intl.ListFormat позволяет использовать стандартные правила локализации JavaScript вместо ручной сборки строк через join() и множества условий для разных языков.
📣 Code Ready | #практика