🤔 Что такое делегирование?
Делегирование событий (Event Delegation) — это техника, при которой мы не навешиваем обработчик на каждый элемент, а ставим один обработчик на родителя и отслеживаем события его потомков.
🚩Как работает делегирование?
Обычный способ (без делегирования)
Если у нас есть 10 кнопок, мы можем повесить обработчик на каждую
Если кнопок 1000, это создаст 1000 обработчиков, что неэффективно.
Если кнопки добавляются динамически (например, из API), обработчик на новые кнопки не сработает.
🟠Делегирование событий (оптимальный способ)
Вместо того чтобы вешать обработчик на каждую кнопку, ставим один обработчик на родительский элемент и проверяем, кто вызвал событие:
🟠Пример с динамическими элементами
Если мы добавляем кнопки динамически, обработчик все равно будет работать
Ставь 👍 и забирай 📚 Базу знаний
Делегирование событий (Event Delegation) — это техника, при которой мы не навешиваем обработчик на каждый элемент, а ставим один обработчик на родителя и отслеживаем события его потомков.
🚩Как работает делегирование?
Обычный способ (без делегирования)
Если у нас есть 10 кнопок, мы можем повесить обработчик на каждую
document.querySelectorAll("button").forEach((btn) => {
btn.addEventListener("click", () => {
console.log("Кнопка нажата");
});
});Если кнопок 1000, это создаст 1000 обработчиков, что неэффективно.
Если кнопки добавляются динамически (например, из API), обработчик на новые кнопки не сработает.
🟠Делегирование событий (оптимальный способ)
Вместо того чтобы вешать обработчик на каждую кнопку, ставим один обработчик на родительский элемент и проверяем, кто вызвал событие:
document.getElementById("container").addEventListener("click", (event) => {
if (event.target.tagName === "BUTTON") {
console.log("Кнопка нажата:", event.target.textContent);
}
});🟠Пример с динамическими элементами
Если мы добавляем кнопки динамически, обработчик все равно будет работать
document.getElementById("container").addEventListener("click", (event) => {
if (event.target.classList.contains("btn")) {
console.log("Нажата кнопка:", event.target.textContent);
}
});
// Добавляем новую кнопку динамически
setTimeout(() => {
const newButton = document.createElement("button");
newButton.classList.add("btn");
newButton.textContent = "Новая кнопка";
document.getElementById("container").appendChild(newButton);
}, 2000);Ставь 👍 и забирай 📚 Базу знаний
👍12🔥1
🤔 Какие статусы есть у Promise?
- pending — в процессе, ещё не завершён;
- fulfilled — успешно завершён (вызван resolve);
- rejected — завершён с ошибкой (вызван reject).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
- pending — в процессе, ещё не завершён;
- fulfilled — успешно завершён (вызван resolve);
- rejected — завершён с ошибкой (вызван reject).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍10
🤔 С помощью чего можно рассчитать идентификатор в js?
В JavaScript есть несколько способов сгенерировать уникальный идентификатор (ID), в зависимости от требований:
🟠 Генерация UUID
UUID (универсально уникальный идентификатор) – это 128-битное число, представленное строкой в формате
Генерация с помощью
Использование библиотеки
🟠Хеш-функции (SHA, MD5)
Если нужно вычислить уникальный идентификатор на основе входных данных (например, строки или объекта), можно использовать хеш-функции.
SHA-256 через
🟠Генерация случайного идентификатора
Если нужна просто случайная строка, можно использовать
Базовая генерация ID
Более безопасный вариант с
🟠Инкрементальные ID
Если нужно просто увеличивающееся число (например, ID для записей в массиве), можно использовать счётчик
🟠Хеширование строки (например, объекта)
Можно создать ID, основываясь на JSON-объекте.
Ставь 👍 и забирай 📚 Базу знаний
В JavaScript есть несколько способов сгенерировать уникальный идентификатор (ID), в зависимости от требований:
🟠 Генерация UUID
UUID (универсально уникальный идентификатор) – это 128-битное число, представленное строкой в формате
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx. Генерация с помощью
crypto.randomUUID() (современный способ) const id = crypto.randomUUID();
console.log(id); // Например: "3d593c8e-7a34-45f7-9a14-2f5f5788d4ec"
Использование библиотеки
uuid import { v4 as uuidv4 } from 'uuid';
const id = uuidv4();
console.log(id); // "f47ac10b-58cc-4372-a567-0e02b2c3d479"🟠Хеш-функции (SHA, MD5)
Если нужно вычислить уникальный идентификатор на основе входных данных (например, строки или объекта), можно использовать хеш-функции.
SHA-256 через
crypto.subtle async function generateHash(input) {
const encoder = new TextEncoder();
const data = encoder.encode(input);
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
return [...new Uint8Array(hashBuffer)].map(b => b.toString(16).padStart(2, '0')).join('');
}
generateHash("hello").then(console.log);
// Например: "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"🟠Генерация случайного идентификатора
Если нужна просто случайная строка, можно использовать
Math.random(). Базовая генерация ID
const id = Math.random().toString(36).substring(2, 10);
console.log(id); // Например: "5g7f8a1z"
Более безопасный вариант с
crypto.getRandomValues()function generateRandomId(length = 16) {
const array = new Uint8Array(length);
crypto.getRandomValues(array);
return [...array].map(b => b.toString(16).padStart(2, '0')).join('');
}
console.log(generateRandomId(8)); // Например: "a3f9b8c7"🟠Инкрементальные ID
Если нужно просто увеличивающееся число (например, ID для записей в массиве), можно использовать счётчик
let counter = 0;
function generateIncrementalId() {
return ++counter;
}
console.log(generateIncrementalId()); // 1
console.log(generateIncrementalId()); // 2
console.log(generateIncrementalId()); // 3
🟠Хеширование строки (например, объекта)
Можно создать ID, основываясь на JSON-объекте.
function hashObject(obj) {
return JSON.stringify(obj)
.split("")
.reduce((hash, char) => {
return ((hash << 5) - hash) + char.charCodeAt(0);
}, 0)
.toString(16);
}
console.log(hashObject({ name: "Alice", age: 25 })); // Например: "-3d4e5f"Ставь 👍 и забирай 📚 Базу знаний
👍8
🤔 Какие плюсы и минусы работы с MobX?
Плюсы:
- Меньше шаблонного кода — изменения происходят «автоматически» благодаря реактивности.
- Простота обучения, ближе к привычному JS-подходу.
- Более высокая производительность при грамотном применении ( @observer ).
- Подходит для средних и больших проектов без сложного boilerplate.
Минусы:
- Магия — сложнее отследить, что и где меняется, особенно для новых участников команды.
- Может вызывать лишние перерендеры, если неправильно использовать observable.
- Меньшая распространённость по сравнению с Redux — меньше обучающих материалов и tooling.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
- Меньше шаблонного кода — изменения происходят «автоматически» благодаря реактивности.
- Простота обучения, ближе к привычному JS-подходу.
- Более высокая производительность при грамотном применении (
- Подходит для средних и больших проектов без сложного boilerplate.
Минусы:
- Магия — сложнее отследить, что и где меняется, особенно для новых участников команды.
- Может вызывать лишние перерендеры, если неправильно использовать observable.
- Меньшая распространённость по сравнению с Redux — меньше обучающих материалов и tooling.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥5👍1
🤔 Как оптимизировать страницы для печати?
Если пользователи захотят распечатать вашу веб-страницу, важно, чтобы она выглядела чисто и профессионально. Для этого используется CSS-медиа-правило
🟠Использование `@media print`
Вы можете задать стили, которые будут применяться только при печати
🟠Убираем ненужные элементы (меню, рекламу, анимации)
Некоторые элементы (например, навигация, футер, кнопки) не нужны при печати, их можно скрыть
🟠Изменяем ширину страницы и текст
Обычно страницы шире, чем лист бумаги. Можно задать
Заменяем цвета на чёрно-белые (экономия чернил)
🟠Добавляем URL ссылок в текст
При печати гиперссылки не работают, поэтому можно показать их адрес
Избегаем разрывов страниц в неудобных местах
Ставь 👍 и забирай 📚 Базу знаний
Если пользователи захотят распечатать вашу веб-страницу, важно, чтобы она выглядела чисто и профессионально. Для этого используется CSS-медиа-правило
@media print, которое позволяет задать специальные стили для печати. 🟠Использование `@media print`
Вы можете задать стили, которые будут применяться только при печати
@media print {
body {
font-size: 12pt; /* Оптимальный размер шрифта */
color: black; /* Убираем цветной текст для экономии чернил */
background: none !important; /* Убираем фон */
}
}🟠Убираем ненужные элементы (меню, рекламу, анимации)
Некоторые элементы (например, навигация, футер, кнопки) не нужны при печати, их можно скрыть
@media print {
nav, .sidebar, .ads, .button {
display: none; /* Скрываем ненужное */
}
}🟠Изменяем ширину страницы и текст
Обычно страницы шире, чем лист бумаги. Можно задать
max-width для удобства@media print {
body {
width: 100%;
max-width: 800px; /* Уменьшаем ширину */
margin: auto; /* Центрируем */
}
}Заменяем цвета на чёрно-белые (экономия чернил)
@media print {
a {
color: black !important; /* Делаем ссылки чёрными */
text-decoration: underline; /* Добавляем подчёркивание */
}
}🟠Добавляем URL ссылок в текст
При печати гиперссылки не работают, поэтому можно показать их адрес
@media print {
a::after {
content: " (" attr(href) ")"; /* Добавляем URL рядом со ссылкой */
font-size: 10pt;
color: gray;
}
}Избегаем разрывов страниц в неудобных местах
@media print {
h1, h2, h3 {
page-break-after: avoid; /* Не разрываем страницу после заголовка */
}
p {
page-break-inside: avoid; /* Не разрываем абзац на две страницы */
}
}Ставь 👍 и забирай 📚 Базу знаний
👍11
🤔 Как защитить cookie от JS?
При установке cookie нужно использовать флаг HttpOnly, чтобы JavaScript не имел к ним доступа. Также полезны флаги Secure (только по HTTPS) и SameSite (ограничение кросс-доступа).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥11👍4
🤔 Как работают плавающие элементы (floats)?
Основные значения
🟠Почему родитель "схлопывается" при `float`?
Когда внутри
Решение 1:
Решение 2:
🟠Как остановить обтекание (`clear`)?
Чтобы отменить обтекание, используется
🚩Почему `float` устарел и что использовать вместо него?
Раньше
Flexbox (
CSS Grid (
Ставь 👍 и забирай 📚 Базу знаний
float – это CSS-свойство, которое позволяет "выплывать" элементу из обычного потока документа и обтекаться другими элементами (например, текстом). Основные значения
float <img src="image.jpg" class="float-img">
<p>Это текст, который будет обтекать картинку.</p>
.float-img {
float: left;
margin-right: 10px;
}🟠Почему родитель "схлопывается" при `float`?
Когда внутри
div есть только float-элементы, браузер считает, что он пустой, потому что float убирает элемент из потока. <div class="container">
<img src="image.jpg" class="float-img">
<p>Текст обтекает картинку.</p>
</div>
.container {
background: lightgray;
}
.float-img {
float: left;
}Решение 1:
overflow: hidden; .container {
overflow: hidden; /* Контейнер теперь учитывает float-элементы */
}Решение 2:
clearfix (старый способ) .container::after {
content: "";
display: block;
clear: both;
}🟠Как остановить обтекание (`clear`)?
Чтобы отменить обтекание, используется
clear. <img src="image.jpg" class="float-img">
<p>Этот текст обтекает картинку.</p>
<div class="clear"></div>
<p>Этот текст пойдёт на новую строку.</p>
.float-img {
float: left;
margin-right: 10px;
}
.clear {
clear: both;
}🚩Почему `float` устарел и что использовать вместо него?
Раньше
float использовали для создания колонок и сеток, но сегодня его заменили: Flexbox (
display: flex;) – лучше для адаптивных макетов. CSS Grid (
display: grid;) – мощный инструмент для сложных сеток. .container {
display: flex;
align-items: center;
}Ставь 👍 и забирай 📚 Базу знаний
👍8
🤔 Какие методы общения имеются в протоколе HTTP?
- GET — получение данных;
- POST — отправка/создание;
- PUT — обновление;
- PATCH — частичное обновление;
- DELETE — удаление;
- OPTIONS, HEAD, CONNECT, TRACE — вспомогательные методы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
- GET — получение данных;
- POST — отправка/создание;
- PUT — обновление;
- PATCH — частичное обновление;
- DELETE — удаление;
- OPTIONS, HEAD, CONNECT, TRACE — вспомогательные методы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍12🔥4💊2
🤔 Какие преимущества у di?
Dependency Injection (DI) – это паттерн проектирования, который помогает разделять зависимости и делает код гибче, тестируемее и поддерживаемее. Вместо того чтобы создавать зависимости внутри класса, они передаются (инъектируются) извне.
🚩Почему DI полезен?
🟠Уменьшает связность кода (Loose Coupling)
Вместо того чтобы жестко привязывать один модуль к другому, DI передает зависимости снаружи.
С DI (гибкость)
🟠Улучшает тестируемость (Unit-тесты проще)
С DI можно подменять зависимости на заглушки (mock, fake, stub).
С DI (можно подменить зависимость)
🟠Улучшает расширяемость (легко менять зависимости)
Допустим, сначала использовали
С DI (добавляем новую зависимость без изменения кода UserService)
🟠Упрощает управление зависимостями (через DI-контейнеры)
В крупных приложениях удобно использовать DI-контейнер (например,
Ставь 👍 и забирай 📚 Базу знаний
Dependency Injection (DI) – это паттерн проектирования, который помогает разделять зависимости и делает код гибче, тестируемее и поддерживаемее. Вместо того чтобы создавать зависимости внутри класса, они передаются (инъектируются) извне.
🚩Почему DI полезен?
🟠Уменьшает связность кода (Loose Coupling)
Вместо того чтобы жестко привязывать один модуль к другому, DI передает зависимости снаружи.
class UserService {
constructor() {
this.db = new Database(); // Прямо создаем зависимость
}
getUser(id) {
return this.db.findUserById(id);
}
}С DI (гибкость)
class UserService {
constructor(db) {
this.db = db; // DI передает зависимость извне
}
getUser(id) {
return this.db.findUserById(id);
}
}
// Передаем нужную зависимость
const database = new Database();
const userService = new UserService(database);🟠Улучшает тестируемость (Unit-тесты проще)
С DI можно подменять зависимости на заглушки (mock, fake, stub).
const userService = new UserService(); // Всегда использует реальную Database
userService.getUser(1); // Как протестировать без реальной БД? 🤔
С DI (можно подменить зависимость)
class FakeDatabase {
findUserById(id) {
return { id, name: "Тестовый пользователь" };
}
}
const fakeDb = new FakeDatabase();
const userService = new UserService(fakeDb);
console.log(userService.getUser(1)); // ✅ Тест без реальной БД🟠Улучшает расширяемость (легко менять зависимости)
Допустим, сначала использовали
MySQLDatabase, но решили перейти на MongoDatabase. class UserService {
constructor() {
this.db = new MySQLDatabase(); // Нужно менять здесь
}
}С DI (добавляем новую зависимость без изменения кода UserService)
const db = new MongoDatabase(); // Просто передаем другую зависимость
const userService = new UserService(db);
🟠Упрощает управление зависимостями (через DI-контейнеры)
В крупных приложениях удобно использовать DI-контейнер (например,
InversifyJS для JavaScript/TypeScript). import "reflect-metadata";
import { Container, injectable, inject } from "inversify";
@injectable()
class Database {
findUserById(id) {
return { id, name: "База данных" };
}
}
@injectable()
class UserService {
constructor(@inject(Database) db) {
this.db = db;
}
getUser(id) {
return this.db.findUserById(id);
}
}
// Настраиваем DI-контейнер
const container = new Container();
container.bind(Database).toSelf();
container.bind(UserService).toSelf();
// Получаем объект с нужными зависимостями
const userService = container.get(UserService);
console.log(userService.getUser(1));
Ставь 👍 и забирай 📚 Базу знаний
👍14
🤔 В каком случае важен порядок: при копировании объекта или массива?
- Для массива порядок важен всегда, так как позиции имеют смысл (это индексированная структура).
- Для объекта порядок чаще не имеет значения, но в некоторых случаях (например, при сериализации) он может быть важен, особенно если зависит от порядка вставки.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
- Для массива порядок важен всегда, так как позиции имеют смысл (это индексированная структура).
- Для объекта порядок чаще не имеет значения, но в некоторых случаях (например, при сериализации) он может быть важен, особенно если зависит от порядка вставки.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍6🔥6
🤔 Как общаться между iframe и самой страницой?
Общение между
Метода
Доступа к
Передачи данных через
🟠`postMessage` – безопасный способ для разных доменов
Метод
🚩Передача данных из `iframe` в родительскую страницу
*Код в
Код в родительской странице (index.html)
🚩Передача данных из родителя в `iframe`
Код в родительской странице (index.html)
Код в
🚩Доступ к `window.frames` и `window.parent` (только если тот же домен!)
Если
Родительская страница →
🚩`localStorage` или `cookies` (если оба окна на одном домене)
Можно сохранять данные в
Запись в
Чтение
Ставь 👍 и забирай 📚 Базу знаний
Общение между
iframe и родительской страницей может происходить с помощью: Метода
postMessage (лучший способ) Доступа к
window.frames или window.parent (если тот же домен) Передачи данных через
localStorage или cookies 🟠`postMessage` – безопасный способ для разных доменов
Метод
window.postMessage() позволяет передавать сообщения между разными окнами (iframe, popup, другие вкладки) даже если они на разных доменах.🚩Передача данных из `iframe` в родительскую страницу
*Код в
iframe (child.html) // Отправляем сообщение родительскому окну
window.parent.postMessage({ type: "hello", data: "Привет, родитель!" }, "*");
Код в родительской странице (index.html)
window.addEventListener("message", (event) => {
console.log("Получено сообщение от iframe:", event.data);
});* в postMessage означает, что сообщение отправляется любому домену. Лучше указывать конкретный, например: window.parent.postMessage({ type: "hello" }, "https://example.com");🚩Передача данных из родителя в `iframe`
Код в родительской странице (index.html)
const iframe = document.getElementById("myIframe");
// Ждём, когда iframe загрузится
iframe.onload = () => {
iframe.contentWindow.postMessage({ type: "greeting", data: "Привет, iframe!" }, "*");
};Код в
iframe (child.html) window.addEventListener("message", (event) => {
console.log("Получено сообщение от родителя:", event.data);
});🚩Доступ к `window.frames` и `window.parent` (только если тот же домен!)
Если
iframe и основная страница находятся на одном домене, можно обращаться к их window напрямую.Родительская страница →
iframe const iframe = document.getElementById("myIframe");
// Получаем объект `window` внутри `iframe`
iframe.contentWindow.document.body.style.backgroundColor = "lightblue";iframe → Родительская страница console.log(window.parent.document.title); // Доступ к заголовку страницы
🚩`localStorage` или `cookies` (если оба окна на одном домене)
Можно сохранять данные в
localStorage или cookies, а другая сторона будет их читать. Запись в
localStorage из iframe localStorage.setItem("message", "Привет от iframe!");Чтение
localStorage в родительской странице console.log(localStorage.getItem("message")); // "Привет от iframe!"Ставь 👍 и забирай 📚 Базу знаний
👍15
🤔 Что известно о жизненном цикле компонента Vue?
Жизненный цикл включает этапы: инициализация (создание и настройка компонента), монтирование (рендеринг в DOM), обновление (перерисовка при изменении данных) и уничтожение (удаление из DOM). Методы жизненного цикла (mounted, updated, destroyed) позволяют выполнять действия на каждом этапе.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Жизненный цикл включает этапы: инициализация (создание и настройка компонента), монтирование (рендеринг в DOM), обновление (перерисовка при изменении данных) и уничтожение (удаление из DOM). Методы жизненного цикла (mounted, updated, destroyed) позволяют выполнять действия на каждом этапе.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥7👍2🤔1
🤔 Что делает omit?
В JavaScript нет встроенного
Реализация
Реализация
Если используете Lodash, можно просто вызвать
Ставь 👍 и забирай 📚 Базу знаний
omit – это функция, которая удаляет указанные ключи из объекта и возвращает новый объект без этих ключей. В JavaScript нет встроенного
omit, но его можно реализовать с помощью деструктуризации и методов Object.fromEntries() или reduce(). Реализация
omit с Object.fromEntries() (современный способ)function omit(obj, keys) {
return Object.fromEntries(
Object.entries(obj).filter(([key]) => !keys.includes(key))
);
}
const user = { name: "Alice", age: 25, password: "123456" };
const safeUser = omit(user, ["password"]);
console.log(safeUser); // { name: "Alice", age: 25 }Реализация
omit с reduce() (альтернативный способ)function omit(obj, keys) {
return Object.keys(obj).reduce((acc, key) => {
if (!keys.includes(key)) acc[key] = obj[key];
return acc;
}, {});
}
const data = { a: 1, b: 2, c: 3 };
console.log(omit(data, ["b"])); // { a: 1, c: 3 }Если используете Lodash, можно просто вызвать
import { omit } from "lodash";
const user = { name: "Alice", age: 25, password: "123456" };
const safeUser = omit(user, ["password"]);
console.log(safeUser); // { name: "Alice", age: 25 }Ставь 👍 и забирай 📚 Базу знаний
👍11🤔1
🤔 Для чего необходим атрибут rel тега <link>?
Атрибут rel (relationship) указывает тип связи между текущим документом и подключаемым ресурсом. Примеры:
- stylesheet — для подключения CSS;
- icon — для favicon;
- preload, dns-prefetch — для оптимизации загрузки.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Атрибут rel (relationship) указывает тип связи между текущим документом и подключаемым ресурсом. Примеры:
- stylesheet — для подключения CSS;
- icon — для favicon;
- preload, dns-prefetch — для оптимизации загрузки.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍9🔥6
🤔 Расскажи про операторы сравнения
Операторы сравнения в JavaScript позволяют сравнивать значения и возвращают
🚩Разница между `==` и `===`
🟠`==` (нестрогое сравнение)
При
🟠`===` (строгое сравнение)
При
🚩🔹 Логические значения в сравнении
JavaScript приводит значения к
🚩Особые случаи
-
-
-
-
Ставь 👍 и забирай 📚 Базу знаний
Операторы сравнения в JavaScript позволяют сравнивать значения и возвращают
true или false. Они часто используются в условиях (if, while) и тернарных операторах. 🚩Разница между `==` и `===`
🟠`==` (нестрогое сравнение)
При
== JavaScript приводит типы перед сравнением. console.log(5 == "5"); // true (строка "5" приводится к числу)
console.log(0 == false); // true (false → 0)
console.log(null == undefined); // true (особый случай)
🟠`===` (строгое сравнение)
При
=== сравниваются и значение, и тип.console.log(5 === "5"); // false (разные типы)
console.log(0 === false); // false (число !== логический тип)
console.log(null === undefined); // false (разные типы)
🚩🔹 Логические значения в сравнении
JavaScript приводит значения к
true или false console.log(1 == true); // true (1 → true)
console.log(0 == false); // true (0 → false)
console.log("" == false); // true ("" → false)
console.log([] == false); // true (пустой массив → false)
console.log(null == false); // false (null не приводится к false)
🚩Особые случаи
-
null == undefined → true (они считаются "похожими"). -
null === undefined → false (разные типы). -
null >= 0 → true (null превращается в 0). -
null > 0 → false (но null >= 0 – true, странно, да?). console.log(null == undefined); // true
console.log(null >= 0); // true
console.log(null > 0); // false (WTF?)
Ставь 👍 и забирай 📚 Базу знаний
👍8
🤔 Как мониторить ошибки JS?
- Через консоль браузера (DevTools);
- Используя системы логирования: Sentry, LogRocket, Bugsnag;
- Локальный лог с console.error и передачей на сервер;
- Performance API, window.onerror, unhandledrejection.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
- Через консоль браузера (DevTools);
- Используя системы логирования: Sentry, LogRocket, Bugsnag;
- Локальный лог с console.error и передачей на сервер;
- Performance API, window.onerror, unhandledrejection.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍5🔥5
🤔 Является ли, drag and drop частью спецификации?
Да! Drag and Drop (перетаскивание) — это часть спецификации HTML5. В браузерах есть встроенный API, который позволяет делать перетаскивание элементов без дополнительных библиотек.
🚩Как работает Drag and Drop API?
В HTML5 можно сделать элемент перетаскиваемым, добавив ему атрибут
🚩Какие события есть в Drag and Drop?
Основные события:
🚩Где используется Drag and Drop?
- Перетаскивание файлов в
- Канбан-доски, как в Trello.
- Онлайн-редакторы, как Figma.
- Игры, где можно перемещать предметы.
🚩Можно ли сделать Drag and Drop без HTML5 API?
Да, можно использовать другие методы:
Через события мыши (
Через CSS
Через JS-библиотеки (
Например, в мобильных браузерах стандартный Drag and Drop API плохо работает, и там лучше использовать события
Ставь 👍 и забирай 📚 Базу знаний
Да! Drag and Drop (перетаскивание) — это часть спецификации HTML5. В браузерах есть встроенный API, который позволяет делать перетаскивание элементов без дополнительных библиотек.
🚩Как работает Drag and Drop API?
В HTML5 можно сделать элемент перетаскиваемым, добавив ему атрибут
draggable="true". Затем срабатывают специальные события, такие как dragstart, drop, dragover и другие. <div id="drag-item" draggable="true">Перетащи меня</div>
<div id="drop-zone">Сюда можно сбросить</div>
<script>
const dragItem = document.getElementById("drag-item");
const dropZone = document.getElementById("drop-zone");
dragItem.addEventListener("dragstart", (event) => {
event.dataTransfer.setData("text/plain", "Данные элемента");
});
dropZone.addEventListener("dragover", (event) => {
event.preventDefault(); // Нужно, чтобы разрешить сброс
});
dropZone.addEventListener("drop", (event) => {
event.preventDefault();
const data = event.dataTransfer.getData("text/plain");
alert("Элемент сброшен: " + data);
});
</script>
🚩Какие события есть в Drag and Drop?
Основные события:
dragstart — когда начали тянуть элемент. drag — когда элемент двигается (срабатывает много раз). dragenter — когда курсор заходит в зону сброса. dragover — когда элемент находится над зоной (нужно preventDefault()). dragleave — когда курсор покидает зону сброса. drop — когда элемент отпущен в зоне сброса. dragend — когда перетаскивание завершено (даже если не сбросили). 🚩Где используется Drag and Drop?
- Перетаскивание файлов в
<input type="file"> (например, загрузка изображений). - Канбан-доски, как в Trello.
- Онлайн-редакторы, как Figma.
- Игры, где можно перемещать предметы.
🚩Можно ли сделать Drag and Drop без HTML5 API?
Да, можно использовать другие методы:
Через события мыши (
mousedown, mousemove, mouseup). Через CSS
position: absolute и transform. Через JS-библиотеки (
Sortable.js, React DnD, Draggable.js). Например, в мобильных браузерах стандартный Drag and Drop API плохо работает, и там лучше использовать события
touchstart, touchmove, touchend.Ставь 👍 и забирай 📚 Базу знаний
👍14🔥1
🤔 Примеры того, что можно использовать в useEffect помимо запросов на сервер:
- Слежение за размерами окна (event listener);
- Установка таймера или интервала;
- Работа с локальным хранилищем (localStorage);
- Изменение мета-тегов или заголовков документа;
- Анимации, интеграции с библиотеками (например, chart.js).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
- Слежение за размерами окна (event listener);
- Установка таймера или интервала;
- Работа с локальным хранилищем (localStorage);
- Изменение мета-тегов или заголовков документа;
- Анимации, интеграции с библиотеками (например, chart.js).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍9🔥3🤔1
🤔 Можем ли мы получить картинку по HTTP?
Да, браузер может получить картинку по HTTP, если сервер отдаёт правильный Content-Type (например, image/jpeg).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Да, браузер может получить картинку по HTTP, если сервер отдаёт правильный Content-Type (например, image/jpeg).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍14🔥3
🤔 Как определить что состояние является глобальным?
Глобальное состояние – это данные, которые должны быть доступны в разных частях приложения. Чтобы определить, является ли состояние глобальным, нужно задать себе несколько вопросов:
🚩Используется ли это состояние в нескольких независимых компонентах?
Если одно и то же состояние необходимо сразу нескольким компонентам, расположенным в разных частях дерева компонентов, скорее всего, его стоит сделать глобальным. В React, если в разных компонентах нужна информация о текущем пользователе (
🚩Должно ли состояние сохраняться при переходе между страницами?
Если данные должны оставаться неизменными при смене страниц, лучше использовать глобальное хранилище (например, Redux, Zustand или React Context). Корзина товаров в интернет-магазине
Авторизация пользователя
Темная/светлая тема приложения
Если данные теряются при смене страницы – это сигнал, что их нужно вынести в глобальное хранилище.
🚩Может ли состояние изменяться в одном месте, а использоваться в другом?
Если одно состояние обновляется в одном компоненте, но влияет на работу нескольких других компонентов, оно должно быть глобальным. В чате, если новое сообщение приходит в одном компоненте (
🚩Зависит ли состояние от URL (адресной строки)?
Иногда состояние можно не делать глобальным, а просто хранить его в URL (в
ID открытого товара:
Фильтры товаров:
Страница чата с пользователем:
Ставь 👍 и забирай 📚 Базу знаний
Глобальное состояние – это данные, которые должны быть доступны в разных частях приложения. Чтобы определить, является ли состояние глобальным, нужно задать себе несколько вопросов:
🚩Используется ли это состояние в нескольких независимых компонентах?
Если одно и то же состояние необходимо сразу нескольким компонентам, расположенным в разных частях дерева компонентов, скорее всего, его стоит сделать глобальным. В React, если в разных компонентах нужна информация о текущем пользователе (
user), лучше хранить её в глобальном состоянии (например, в Context или Redux). // Глобальное состояние (например, Context API)
const UserContext = createContext();
function App() {
const [user, setUser] = useState({ name: "Иван", isLoggedIn: true });
return (
<UserContext.Provider value={user}>
<Navbar />
<Profile />
</UserContext.Provider>
);
}
function Navbar() {
const user = useContext(UserContext);
return <div>Привет, {user.name}!</div>;
}
function Profile() {
const user = useContext(UserContext);
return <div>Профиль пользователя: {user.name}</div>;
}
🚩Должно ли состояние сохраняться при переходе между страницами?
Если данные должны оставаться неизменными при смене страниц, лучше использовать глобальное хранилище (например, Redux, Zustand или React Context). Корзина товаров в интернет-магазине
Авторизация пользователя
Темная/светлая тема приложения
Если данные теряются при смене страницы – это сигнал, что их нужно вынести в глобальное хранилище.
🚩Может ли состояние изменяться в одном месте, а использоваться в другом?
Если одно состояние обновляется в одном компоненте, но влияет на работу нескольких других компонентов, оно должно быть глобальным. В чате, если новое сообщение приходит в одном компоненте (
ChatInput), а отображается в другом (ChatList), логично хранить все сообщения в глобальном состоянии. const ChatContext = createContext();
function ChatProvider({ children }) {
const [messages, setMessages] = useState([]);
const sendMessage = (text) => {
setMessages([...messages, { text, id: Date.now() }]);
};
return (
<ChatContext.Provider value={{ messages, sendMessage }}>
{children}
</ChatContext.Provider>
);
}
function ChatList() {
const { messages } = useContext(ChatContext);
return messages.map((msg) => <p key={msg.id}>{msg.text}</p>);
}
function ChatInput() {
const { sendMessage } = useContext(ChatContext);
const [text, setText] = useState("");
return (
<input
value={text}
onChange={(e) => setText(e.target.value)}
onKeyPress={(e) => {
if (e.key === "Enter") {
sendMessage(text);
setText("");
}
}}
/>
);
}
🚩Зависит ли состояние от URL (адресной строки)?
Иногда состояние можно не делать глобальным, а просто хранить его в URL (в
query-параметрах или path). ID открытого товара:
/products/123 Фильтры товаров:
/shop?category=shoes&sort=price Страница чата с пользователем:
/chat?user=ivanСтавь 👍 и забирай 📚 Базу знаний
👍6🔥1
🤔 Как передать данные из родительского компонента в дочерний?
Данные передаются с использованием props.
1. Родительский компонент передаёт данные через атрибуты в дочерний компонент.
2. Дочерний компонент принимает их, определяя props в своей конфигурации.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
1. Родительский компонент передаёт данные через атрибуты в дочерний компонент.
2. Дочерний компонент принимает их, определяя props в своей конфигурации.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍6🔥6