Вёрстка сайтов | HTML, CSS, JS
4.64K subscribers
814 photos
1 video
4 files
1.28K links
👋 Привет, друг!

В этом канале я выкладываю структурированные, обучающие уроки и материалы по вёрстке сайтов и фронтенду.
Присоединяйся и начинай учиться!

Связь: @Tigran1963
Download Telegram
Что будет в консоли? Асинхронные функции: Порядок выполнения с await

async function f() {
console.log(1);
const promise = new Promise((resolve) => {
console.log(2);
setTimeout(() => {
console.log(3);
resolve('готово!');
console.log(4);
});
});
console.log(5);

const result = await promise;
console.log(6);
console.log(result);
return 'Result';
}

f();
console.log(7);


Ответ:
async function f() {
console.log(1); // Синхронно #1
const promise = new Promise((resolve) => {
console.log(2); // Синхронно #2 (в executor)
setTimeout(() => { // Макрозадача #1
console.log(3); // Внутри макрозадачи #1.1
resolve('готово!'); // Разрешает промис, ставит возобновление 'f' в микрозадачи
console.log(4); // Внутри макрозадачи #1.2
}, 0); // Минимальная задержка
});
console.log(5); // Синхронно #3

// 'f' приостанавливается здесь, ждет разрешения 'promise'
const result = await promise; // Возобновится как микрозадача после resolve()

// Возобновление 'f' (Микрозадача #1)
console.log(6); // После await #1
console.log(result); // После await #2
return 'Result';
}

f(); // Запускает 'f'
console.log(7); // Синхронно #4 (после запуска 'f', но до завершения await)

// Порядок вывода:
// 1 ← Синхронно #1
// 2 ← Синхронно #2
// 5 ← Синхронно #3
// 7 ← Синхронно #4
// 3 ← Макрозадача #1.1
// 4 ← Макрозадача #1.2 (Promise resolved)
// 6 ← Микрозадача #1 (Возобновление f, после await #1)
// "готово!" ← Микрозадача #1 (Возобновление f, после await #2)


#домашка
Задача из hackfrontend.com
1
Как улучшить UX c помощью микровзаимодействий?

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

1. Обратная связь при нажатии
Добавьте анимацию или изменение цвета кнопок при клике. Такие отклики дают пользователю знать, что его действие принято системой. Пример:
button {
transition: transform 0.1s ease;
}
button:active {
transform: scale(0.95);
}


2. Подсказки и хинты

Появление подсказок при наведении курсора помогает пользователю понять, как работает интерфейс. Используйте CSS hover для простых анимаций и плавного появления элементов.
.tooltip {
opacity: 0;
transition: opacity 0.3s ease;
}
button:hover + .tooltip {
opacity: 1;
}


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

4. Подсветка ошибок
Если пользователь заполняет форму, дайте ему моментальную обратную связь: ошибки в реальном времени (в поле ввода, например, текст становится красным) помогут не допустить ошибок и улучшить UX.

5. Интерактивные уведомления
Ненавязчивые уведомления помогут пользователю ориентироваться в приложении и быстрее находить нужные данные. Используйте CSS и JS, чтобы уведомления появлялись на экране и исчезали, не прерывая основной процесс.

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

#полезности
👍3
Графика на Canvas для начинающих

Читать 👨‍💻

#теория
👍1
5 Советов для Ускорения HTML-верстки

Верстка — это не только про точность, но и про скорость работы. Если вы хотите писать код быстрее, но без потери качества, вот несколько простых и полезных советов:

1. Используйте Emmet для ускорения работы
Emmet — это встроенный инструмент большинства редакторов кода. Он позволяет создавать сложные структуры HTML за пару секунд.
Пример:
div.container>header+main+footer 

Расширяется в:
<div class="container">  
<header></header>
<main></main>
<footer></footer>
</div>

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

2. Организуйте структуру проекта
Пишите код так, чтобы любой мог его понять:
Разделяйте стили и скрипты в отдельные файлы.
Придерживайтесь единого стиля именования классов (например, BEM).
Пример:
<div class="menu__item menu__item--active">Главная</div>  


3. Работайте с семантикой
Семантические теги (например, <header>, <article>, <nav>) делают ваш код понятнее и лучше для SEO. Используйте их вместо универсальных <div>.

4. Добавляйте комментарии
Комментарии помогут вам или вашим коллегам быстрее разобраться в коде. Например:
<!-- Главное меню сайта -->  
<nav>...</nav>


5. Проверяйте верстку на всех устройствах
Обязательно тестируйте:
В браузерах: Chrome, Firefox, Safari.
На разных устройствах: телефонах, планшетах и ноутбуках.
Попробуйте бесплатные инструменты, такие как Chrome DevTools, чтобы посмотреть, как ваш сайт выглядит на экранах с разным разрешением.
Ваш HTML-код — это не просто текст, это фундамент любого сайта. Чем чище и качественнее он будет, тем проще с ним работать другим разработчикам.

#полезнаястатья
👍1🔥1
Задача: Фильтрация и сортировка списка пользователей

Описание:
У вас есть массив объектов, представляющих пользователей. Каждый объект содержит следующие свойства: name (имя пользователя), age (возраст пользователя) и isActive (булево значение, указывающее, активен ли пользователь).

Ваша задача:
Отфильтровать массив, оставив только активных пользователей.
Отсортировать активных пользователей по возрасту в порядке возрастания.
Вернуть массив имён отсортированных активных пользователей.
Пример входных данных:
const users = [
{ name: 'Alice', age: 25, isActive: true },
{ name: 'Bob', age: 30, isActive: false },
{ name: 'Charlie', age: 20, isActive: true },
{ name: 'David', age: 35, isActive: true },
{ name: 'Eve', age: 28, isActive: false }
];

Пример выходных данных:
['Charlie', 'Alice', 'David']

Указания:
Используйте метод filter() для фильтрации активных пользователей.
Используйте метод sort() для сортировки пользователей по возрасту.
Используйте метод map() для извлечения имён пользователей.

#домашка
Какое св-во в Grid управляет количеством строк или столбцов
Anonymous Quiz
7%
grid-auto-flow
6%
grid-gap
55%
grid-template
32%
grit-template-rows
👎1
JS Вопрос:

Какой метод document возвращает массив со всеми найденными элементами, которые соответствуют указанному селектору?
Anonymous Quiz
13%
querySelector()
66%
querySelectorAll()
5%
getElementByID()
8%
getAll()
7%
Посмотреть ответы
👍2
Задача: Реализовать функцию для "сворачивания" массива

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

Пример:
const input = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];
const result = countOccurrences(input);
console.log(result);
// Ожидаемый вывод:
// {
// apple: 3,
// banana: 2,
// orange: 1
// }

Условия:
Функция должна корректно работать с массивами любых типов данных, например, строк, чисел, или даже объектов, если в них используется одинаковая ссылка.
Постарайтесь реализовать решение с минимальным количеством проходов по массиву.

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

#домашка
Как корректно измерять производительность JavaScript-кода

При оценке скорости выполнения кода часто допускается одна и та же ошибка — измерение времени одной операции:


const start = performance.now();

"the sky is blue".split(' ').reverse().join(' ');

const end = performance.now();
console.log('Время выполнения =', end - start);


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

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

Во-вторых, влияет JIT-компиляция. Движки, такие как V8 JavaScript engine, сначала исполняют код в базовом режиме, а затем оптимизируют его. Поэтому первый запуск не отражает реальную производительность.

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

Как измерять корректно
1. Выполняйте операцию многократно


const ITERATIONS = 1_000_000;

const start = performance.now();

for (let i = 0; i < ITERATIONS; i++) {
"the sky is blue".split(' ').reverse().join(' ');
}

const end = performance.now();

console.log('Среднее время:', (end - start) / ITERATIONS);


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

2. Используйте «прогрев» (warm-up)


for (let i = 0; i < 10000; i++) {
"test string".split(' ').reverse().join(' ');
}


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

3. Сравнивайте функции изолированно

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

4. Используйте специализированные инструменты

Для более точного анализа подойдут:

* performance.now()
* console.time()
* библиотеки вроде Benchmark.js

#js
👍1
TypeScript: что такое interface и зачем он нужен

Когда начинаешь изучать TypeScript, одним из первых важных понятий становится interface.

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

Простой пример:

name: string
age: number
isAdmin: boolean
}


Теперь если создать объект пользователя, TypeScript будет проверять, соответствует ли он этой структуре:

name: 'Tigran',
isAdmin: true
}


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

Почему это удобно:
1. Код становится понятнее
Когда видишь User, уже не нужно гадать, какие поля должны быть у объекта.
2. Меньше ошибок
TypeScript не даст случайно передать строку вместо числа или забыть важное поле.
3. Удобно типизировать параметры функций


name: string
age: number
}

function printUser(user: User) {
console.log(`${user.name}, ${user.age}`)
}


4. Можно описывать не только объекты, но и методы

brand: string
year: number
startEngine: () => void
}

Также в interface можно делать необязательные свойства через ?
```interface Product {
title: string
price: number
discount?: number
}


Это значит, что discount может быть, а может и не быть.

Важно понимать:
interface не создаёт объект и не добавляет логику в JavaScript. Он нужен только для проверки типов во время разработки.

Когда использовать interface:
когда нужно описать структуру объекта, который будет использоваться в разных местах проекта: пользователи, товары, ответы от API, параметры функций, props компонентов и так далее.

Итог:
interface в TypeScript нужен, чтобы задавать понятную и строгую форму данных. Это делает код чище, безопаснее и удобнее в поддержке.

#ts
👍31