Реактивность в CSS
#CSS #JS #Лаборатория_веб_платформы
Реактивность — это когда изменение состояния одной штуки приводит к реакции — изменению состояния других штук. К примеру, если температура воздуха опустилась ниже 0°C, вода замёрзнет и сожмётся.
Реактивность в программировании тоже про реакцию на изменение состояния. Пример:
Число
Такая «ручная реактивность» неоптимальна. Современные JS-фреймворки, например Svelte, умеют в автоматическую реактивность. Для этого «реактивное» значение нужно явно определить, а фреймворк будет автоматически следить за изменением «источников» и пересчитывать состояние:
Нативные переменные в CSS — сразу реактивные «из коробки». Браузер будет следить за их изменением и пересчитывать все зависящие от них значения.
#CSS #JS #Лаборатория_веб_платформы
Реактивность — это когда изменение состояния одной штуки приводит к реакции — изменению состояния других штук. К примеру, если температура воздуха опустилась ниже 0°C, вода замёрзнет и сожмётся.
Реактивность в программировании тоже про реакцию на изменение состояния. Пример:
let doubled = number * 2;
// doubled равно 4
Число
number — это переменная состояния. Удвоенное число doubled «выводится» из этой переменной. Если число меняется, то удвоенное число по умолчанию не «обновится», нужно явно вычислить его ещё раз:
let doubled = number * 2;
// doubled равно 4
number = 5;
doubled = number * 2;
// doubled равно 10
Такая «ручная реактивность» неоптимальна. Современные JS-фреймворки, например Svelte, умеют в автоматическую реактивность. Для этого «реактивное» значение нужно явно определить, а фреймворк будет автоматически следить за изменением «источников» и пересчитывать состояние:
$: doubled = number * 2;
// doubled равно 4
number = 5;
// doubled стало 10
Нативные переменные в CSS — сразу реактивные «из коробки». Браузер будет следить за их изменением и пересчитывать все зависящие от них значения.
</div>
<div class="block modified">
</div>
--number: 20px;
--doubled: calc(var(--number) * 2);
width: var(--doubled);
/* width равно 40px */
}
.block.modified {
--number: 50px;
/* width стало 100px */
}
❤1
Стрелочная функция и new
#JS #Лаборатория_веб_платформы
Обычная функция
Стрелочная функция не может использоваться как конструктор. При попытке использования выбросится ошибка TypeError.
#JS #Лаборатория_веб_платформы
Обычная функция
function может использоваться в качестве конструктора:
this.color = color;
}
const blackDog = new Dog('black');
Стрелочная функция не может использоваться как конструктор. При попытке использования выбросится ошибка TypeError.
this.color = color;
}
const blackDog = new Dog('black');
// TypeError: Dog is not a constructor
❤1
DOM и JS-фреймворки
#JS #фреймворки #Лаборатория_веб_платформы
В фреймворках React и Vue используется концепт «Virtual DOM». Это представление «реального» UI, то есть DOM-а в браузере пользователя, в виде объекта в JS. Этот объект хранится в памяти браузера и представляет собой такую же иерархическую структуру, что и настоящее DOM-дерево. Упрощённо говоря — так:
Зачем делать такую копию DOM-а в памяти? Это нужно для оптимизации работы с настоящим DOM-ом в браузере. Возьмём пример: в браузере отрисовано 1000 DOM-нод, среди них нужно заменить одну ноду. Брать и заменять всё содержимое родительской ноды — неоптимально.
Лучше будет:
1. Хранить предыдущее и новое состояние (в памяти, виртуальном DOM-е).
2. По специальному алгоритму найти различия между двумя состояниями.
3. И затем синхронизировать реальное и виртуальное представление DOM-а, обновив точечно только нужные части дерева.
Этот процесс «сверки» нод в React называется reconciliation (в русском уже адаптировалось «реконсиляция»). Полное сравнение двух DOM-деревьев может быть довольно «дорогим» по ресурсам, особенно когда нод в них много. Поэтому во фреймворках в алгоритмах сверки и обновления заложены допущения, позволяющие избежать трат слишком больших ресурсов компьютера.
Например:
1. В повторяющихся наборах (списках, листингах) каждая нода помечается уникальным «ключом» — атрибутом key. По таким «подсказкам от разработчика» (уникальным идентификаторам, хэшам) фреймворку легче сравнивать ноды в DOM-деревьях: можно распознать изменение, не залезая внутрь ноды и не ориентируясь на её очерёдность в списке. Задача сводится к работе с «набором ключей» (HashMap): фреймворк определяет появление элементов с новыми ключами или изменение порядка элементов по их ключам.
2. Если меняется тип DOM-ноды, например, с
#JS #фреймворки #Лаборатория_веб_платформы
В фреймворках React и Vue используется концепт «Virtual DOM». Это представление «реального» UI, то есть DOM-а в браузере пользователя, в виде объекта в JS. Этот объект хранится в памяти браузера и представляет собой такую же иерархическую структуру, что и настоящее DOM-дерево. Упрощённо говоря — так:
<h1>Title</h1>
</div>
const virtualNode = {
type: 'div',
props: {
className: 'box',
children: [{
type: 'h1',
props: {
children: [ 'Title' ]
}
}]
}
}
Зачем делать такую копию DOM-а в памяти? Это нужно для оптимизации работы с настоящим DOM-ом в браузере. Возьмём пример: в браузере отрисовано 1000 DOM-нод, среди них нужно заменить одну ноду. Брать и заменять всё содержимое родительской ноды — неоптимально.
Лучше будет:
1. Хранить предыдущее и новое состояние (в памяти, виртуальном DOM-е).
2. По специальному алгоритму найти различия между двумя состояниями.
3. И затем синхронизировать реальное и виртуальное представление DOM-а, обновив точечно только нужные части дерева.
Этот процесс «сверки» нод в React называется reconciliation (в русском уже адаптировалось «реконсиляция»). Полное сравнение двух DOM-деревьев может быть довольно «дорогим» по ресурсам, особенно когда нод в них много. Поэтому во фреймворках в алгоритмах сверки и обновления заложены допущения, позволяющие избежать трат слишком больших ресурсов компьютера.
Например:
1. В повторяющихся наборах (списках, листингах) каждая нода помечается уникальным «ключом» — атрибутом key. По таким «подсказкам от разработчика» (уникальным идентификаторам, хэшам) фреймворку легче сравнивать ноды в DOM-деревьях: можно распознать изменение, не залезая внутрь ноды и не ориентируясь на её очерёдность в списке. Задача сводится к работе с «набором ключей» (HashMap): фреймворк определяет появление элементов с новыми ключами или изменение порядка элементов по их ключам.
2. Если меняется тип DOM-ноды, например, с
<p> на <div>, то фреймворк заменит саму ноду и все её дочерние элементы целиком.❤1
Плавный скролл в CSS
#CSS #Лаборатория_веб_платформы
Переход по якорным ссылкам внутри страницы мгновенно «перебрасывает» к нужному месту:
Такое моментальное перемещение может вызвать непонимание, что именно произошло, а это плохой UX. Именно поэтому такой скролл лучше делать плавным, чтобы было видно явно, откуда скролл «выехал» и где остановился.
Нативное решение можно сделать и на JS, и на CSS.
JS-решение
В метод
CSS-решение
Контейнеру со скроллом задаётся свойство
Когда скролл к элементу произошёл, то верхняя часть экрана «упрётся» прямо в блок, к которому произошёл скролл. Чтобы такого «прилипания» не произошло, можно воспользоваться свойством
Таким образом от верхнего края экрана до блока, к которому произошёл скролл, останется «зазор» в 20 пикселей.
#CSS #Лаборатория_веб_платформы
Переход по якорным ссылкам внутри страницы мгновенно «перебрасывает» к нужному месту:
<a class="back-to-top" href="#top">Scroll to Top</a>
Такое моментальное перемещение может вызвать непонимание, что именно произошло, а это плохой UX. Именно поэтому такой скролл лучше делать плавным, чтобы было видно явно, откуда скролл «выехал» и где остановился.
Нативное решение можно сделать и на JS, и на CSS.
JS-решение
В метод
scroll или scrollIntoView передаётся настройка behavior: 'smooth':
backLink.addEventListener('click', (e) => {
// отключаем «перескок» по умолчанию
e.preventDefault();
// плавно скроллим к самому верху страницы
window.scroll({ top: 0, behavior: 'smooth' });
// или скроллим к элементу с id="top"
document.querySelector('#top').scrollIntoView({ behavior: 'smooth' });
});
CSS-решение
Контейнеру со скроллом задаётся свойство
scroll-behavior. Это может быть и вся страница, то есть контейнер самого верхнего уровня — html:
scroll-behavior: smooth;
}
Когда скролл к элементу произошёл, то верхняя часть экрана «упрётся» прямо в блок, к которому произошёл скролл. Чтобы такого «прилипания» не произошло, можно воспользоваться свойством
scroll-margin, которое задаст элементу внешние отступы, учитывающиеся только при скролле.
scroll-margin-top: 20px;
}
Таким образом от верхнего края экрана до блока, к которому произошёл скролл, останется «зазор» в 20 пикселей.
❤1