Разбираем insertAdjacentHTML() — вставляем HTML без повторного парсинга существующего содержимого!
Для добавления разметки в элемент иногда используют
Но это не точечная вставка. Браузер получает текущее содержимое как строку, добавляет новую разметку и снова устанавливает
В результате существующие дочерние DOM-узлы могут быть заменены новыми:
Для вставки HTML без повторного парсинга существующего содержимого есть
Метод принимает позицию вставки и HTML-строку:
Например, вставка первым дочерним элементом:
А
Что важно:
🔥 В отличие от
📣 Code Ready | #практика
Для добавления разметки в элемент иногда используют
innerHTML +=:list.innerHTML += '<li>Новый элемент</li>';
Но это не точечная вставка. Браузер получает текущее содержимое как строку, добавляет новую разметку и снова устанавливает
innerHTML.В результате существующие дочерние DOM-узлы могут быть заменены новыми:
const button = list.querySelector('button');
list.innerHTML += '<li>Новый</li>';
console.log(
list.querySelector('button') === button
);
// falseДля вставки HTML без повторного парсинга существующего содержимого есть
insertAdjacentHTML():const button = list.querySelector('button');
list.insertAdjacentHTML(
'beforeend',
'<li>Новый</li>'
);
console.log(
list.querySelector('button') === button
);
// trueМетод принимает позицию вставки и HTML-строку:
beforebegin
afterbegin
beforeend
afterend
Например, вставка первым дочерним элементом:
list.insertAdjacentHTML(
'afterbegin',
'<li>Первый</li>'
);
А
afterend вставляет разметку после самого элемента:list.insertAdjacentHTML(
'afterend',
'<p>После списка</p>'
);
beforebegin и afterend работают относительно родительского элемента, поэтому целевой элемент должен иметь родителя.Что важно:
insertAdjacentHTML() передает строку HTML-парсеру и не выполняет санитизацию. Передача недоверенного HTML создает риск XSS. Для обычного текста используйте textContent или insertAdjacentText(), а недоверенный HTML необходимо корректно санитизировать.innerHTML +=, insertAdjacentHTML() позволяет вставить новый HTML-фрагмент в нужную позицию, не заменяя уже существующие DOM-узлы.Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤7🔥5
Почему change не всегда подходит для отслеживания изменений в input!
При работе с формами часто пытаются отслеживать ввод через событие
Но для текстовых полей это не всегда правильный вариант.
Если интерфейс должен реагировать непосредственно во время ввода, используется событие
Теперь обработчик вызывается при каждом изменении значения:
При этом
Например, динамический поиск обычно строят так:
Частая ошибка — использовать
Но эти события решают разные задачи.
У события
Например, можно определить, было ли действие вставкой текста, удалением символа или вставкой из буфера обмена.
Если обработчик
При этом у
Важный нюанс: программное изменение
Браузер отличает изменение через код от реального пользовательского ввода. Если приложению нужно уведомить другие части системы, событие можно вызвать отдельно:
Но такое событие будет синтетическим (
В сложных редакторах также учитывают IME-ввод, например при работе с китайской, японской или корейской раскладкой. Во время композиции можно проверить:
🔥 Главное правило простое: если нужно реагировать на процесс редактирования в реальном времени — используйте
📣 Code Ready | #практика
При работе с формами часто пытаются отслеживать ввод через событие
change:input.addEventListener('change', event => {
console.log(event.target.value);
});Но для текстовых полей это не всегда правильный вариант.
change срабатывает не при каждом изменении текста, а после того, как пользователь изменил значение и завершил редактирование, например покинул поле.Если интерфейс должен реагировать непосредственно во время ввода, используется событие
input:input.addEventListener('input', event => {
console.log(event.target.value);
});Теперь обработчик вызывается при каждом изменении значения:
J
Ja
Jav
Java
При этом
input — это не просто реакция на нажатие клавиш. Событие возникает и при других действиях пользователя, например при вставке текста, удалении, вставке через контекстное меню или перемещении текста через drag & drop.Например, динамический поиск обычно строят так:
search.addEventListener('input', event => {
const query = event.target.value.trim();
filterItems(query);
});Частая ошибка — использовать
keyup как замену input:input.addEventListener('keyup', handler);Но эти события решают разные задачи.
keyup реагирует только на отпускание клавиши, поэтому он не поймает вставку мышью, автозаполнение браузера и другие изменения значения без клавиатуры.У события
input есть дополнительная информация через InputEvent:input.addEventListener('input', event => {
console.log(event.inputType);
});Например, можно определить, было ли действие вставкой текста, удалением символа или вставкой из буфера обмена.
Если обработчик
input запускает тяжёлую операцию или запрос к API, обычно используют debounce, чтобы не выполнять действие после каждого символа:search.addEventListener(
'input',
debounce(event => {
fetchResults(event.target.value);
}, 300)
);
При этом у
change остаются свои правильные сценарии. Например, для <select> он хорошо подходит, потому что важен момент выбора нового значения:select.addEventListener('change', event => {
updateLanguage(event.target.value);
});Важный нюанс: программное изменение
value само по себе не создаёт событие input:input.value = 'JavaScript';
Браузер отличает изменение через код от реального пользовательского ввода. Если приложению нужно уведомить другие части системы, событие можно вызвать отдельно:
input.value = 'JavaScript';
input.dispatchEvent(
new Event('input', { bubbles: true })
);
Но такое событие будет синтетическим (
isTrusted === false), а не настоящим действием пользователя.В сложных редакторах также учитывают IME-ввод, например при работе с китайской, японской или корейской раскладкой. Во время композиции можно проверить:
input.addEventListener('input', event => {
if (event.isComposing) {
return;
}
processValue(event.target.value);
});input. Если нужно получить факт завершённого изменения значения — подходит change. Если нужно отслеживать только действия клавиатуры — используйте keyup, понимая его ограничения.Please open Telegram to view this post
VIEW IN TELEGRAM
❤13🤝10👍7🔥1
Разбираем AbortController и AbortSignal, с помощью которых можно отменять fetch-запросы и другие поддерживаемые операции, проверять состояние и причину отмены, прерывать собственную асинхронную логику, задавать таймауты и объединять несколько сигналов отмены. Используется для управления жизненным циклом операций, предотвращения лишней работы и корректной очистки ресурсов.Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥19👍9🤝3❤2
В контейнер
<nav> помещаются основные ссылки, по которым пользователь сможет быстро перейти на нужный раздел сайта.В <nav> обычно размещают:
• главное меню сайта;
• навигацию по разделам;
• оглавление статьи или документа;
• ссылки для перехода между связанными страницами.
При этом не каждую группу ссылок стоит помещать в
<nav>. Тег предназначен прежде всего для основных навигационных блоков, а обычный набор вспомогательных ссылок может оставаться без него.Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤9🤝4🔥2
This media is not supported in your browser
VIEW IN TELEGRAM
В репозитории собраны полезные ресурсы по веб-разработке: HTML, CSS, JavaScript, React, Node.js, Webpack, Git, тестирование и архитектура frontend-приложений. Есть статьи, курсы, видео, книги, разборы задач и практические материалы по асинхронности, ООП, алгоритмам, паттернам проектирования и созданию реальных проектов.
Оставляю ссылочку: GitHub📱
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9🤝7👍4
Прокачать навыки вёрстки и фронтенда можно в телеграм!
В этом канале опытный верстальщик делится структурированными уроками и различными материалами по HTML, CSS, JS, а также советами по заработку на фрилансе.
Канал будет полезен:
1. начинающим и опытным верстальщикам
2. программистам
3. веб-дизайнерам
Научиться и зарабатывать на верстке:
@free_html_lessons
В этом канале опытный верстальщик делится структурированными уроками и различными материалами по HTML, CSS, JS, а также советами по заработку на фрилансе.
Канал будет полезен:
1. начинающим и опытным верстальщикам
2. программистам
3. веб-дизайнерам
Научиться и зарабатывать на верстке:
@free_html_lessons
Не давай стилям компонента протекать во вложенные компоненты!
Частая проблема большого UI: стилизуем весь контент внутри компонента, а потом эти правила неожиданно задевают другой компонент, вложенный внутрь.
Обычный селектор по вложенности затронет оба
С
Первый
Это особенно удобно для CMS-контента,
И не приходится усложнять селекторы:
Вместо описания всей структуры мы задаём архитектурную границу:
🔥
📣 Code Ready | #совет
Частая проблема большого UI: стилизуем весь контент внутри компонента, а потом эти правила неожиданно задевают другой компонент, вложенный внутрь.
<article class="article">
<p>Текст статьи</p>
<div class="widget"><p>Текст виджета</p></div>
</article>
Обычный селектор по вложенности затронет оба
<p>:.article p {
margin-block: 1em;
}С
@scope можно задать не только начало области, но и место, перед которым действие правил заканчивается.@scope (.article) to (.widget) {
p { margin-block: 1em; }
}Первый
<p> получит стиль, а <p> внутри .widget — уже нет. .widget здесь является нижней границей scope, поэтому элементы внутри неё исключаются из этой области.Это особенно удобно для CMS-контента,
markdown, rich-text и дизайн-систем, где внутрь одного компонента могут попадать другие независимые компоненты.И не приходится усложнять селекторы:
.article > p,
.article > section > p {
/* попытка описать структуру DOM */
}
Вместо описания всей структуры мы задаём архитектурную границу:
@scope (.content) to (.component) {
a { text-decoration: underline; }
}@scope специально предназначен для ограничения селекторов конкретным DOM-поддеревом без наращивания специфичности и жёсткой привязки CSS к структуре разметки.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13❤6🤝4👍2
Тег
<picture> позволяет браузеру выбирать подходящую версию изображения в зависимости от размера экрана, поддерживаемого формата или других условий.Внутри <picture> обычно размещают:
• <source> — задаёт альтернативные версии изображения;
• srcset — указывает файл изображения;
• media — определяет условие выбора, например ширину экрана;
• type — указывает MIME-тип формата, например image/avif;
• <img> — служит основным или резервным вариантом изображения.
Браузер анализирует каждый тег
<source> по порядку, останавливается на первом подходящем под текущие условия и отображает картинку из атрибута srcset. Другие теги не анализируются. Если тег <picture> не поддерживается браузером или ни один из тегов <source> не подходит под условия, то отображается картинка из тега <img>.Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤5🤝3🔥1