Чтобы отслеживать изменения свойств объекта в JavaScript, можно использовать несколько методов, каждый из которых подходит для различных случаев.
Proxy
является мощным и гибким способом перехвата и настройки операций с объектами, включая чтение и запись свойств.const handler = {
get(target, property) {
console.log(`Getting value of ${property}`);
return target[property];
},
set(target, property, value) {
console.log(`Setting value of ${property} to ${value}`);
target[property] = value;
return true;
}
};
const person = {
name: 'Alice',
age: 25
};
const proxyPerson = new Proxy(person, handler);
proxyPerson.name = 'Bob'; // Setting value of name to Bob
console.log(proxyPerson.name); // Getting value of name // Bob
Object.defineProperty
позволяет определить новое или изменить существующее свойство непосредственно на объекте, позволяя добавить геттеры и сеттеры для отслеживания изменений.const person = {
_name: 'Alice',
_age: 25
};
Object.defineProperty(person, 'name', {
get() {
console.log('Getting name');
return this._name;
},
set(value) {
console.log(`Setting name to ${value}`);
this._name = value;
}
});
Object.defineProperty(person, 'age', {
get() {
console.log('Getting age');
return this._age;
},
set(value) {
console.log(`Setting age to ${value}`);
this._age = value;
}
});
person.name = 'Bob'; // Setting name to Bob
console.log(person.name); // Getting name // Bob
person.age = 30; // Setting age to 30
console.log(person.age); // Getting age // 30
MobX — это библиотека для управления состоянием, которая делает состояния наблюдаемыми и автоматически синхронизирует их с пользовательским интерфейсом.
import { observable, autorun } from 'mobx';
const person = observable({
name: 'Alice',
age: 25,
setName(name) {
this.name = name;
},
setAge(age) {
this.age = age;
}
});
// Автоматически вызываемая функция при изменении наблюдаемого состояния
autorun(() => {
console.log(`Name: ${person.name}, Age: ${person.age}`);
});
person.setName('Bob'); // Name: Bob, Age: 25
person.setAge(30); // Name: Bob, Age: 30
Для отслеживания изменений в DOM можно использовать
MutationObserver
. Это не напрямую связано с объектами, но полезно для отслеживания изменений в элементах DOM.const targetNode = document.getElementById('target');
const config = { attributes: true, childList: true, subtree: true };
const callback = function(mutationsList, observer) {
for(let mutation of mutationsList) {
if (mutation.type === 'childList') {
console.log('A child node has been added or removed.');
}
else if (mutation.type === 'attributes') {
console.log('The ' + mutation.attributeName + ' attribute was modified.');
}
}
};
const observer = new MutationObserver(callback);
observer.observe(targetNode, config);
targetNode.setAttribute('data-test', 'value');
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18❤2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥7
Оптимизация сайта включает в себя несколько стратегий и техник, направленных на улучшение производительности, скорости загрузки и пользовательского опыта.
Используйте инструменты для сжатия изображений (например, TinyPNG, ImageOptim) без значительной потери качества. Используйте современные форматы изображений, такие как WebP, которые обеспечивают лучшее сжатие по сравнению с JPEG и PNG. Загружайте изображения по мере их появления в области видимости пользователя (атрибут
loading="lazy"
в HTML).Уменьшите размер CSS, JavaScript и HTML-файлов с помощью инструментов, таких как UglifyJS, CSSNano, HTMLMinifier. Сократите количество HTTP-запросов, объединив несколько CSS или JavaScript файлов в один.
Храните копии вашего сайта на серверах по всему миру, чтобы уменьшить время загрузки для пользователей из разных регионов.
Настройте заголовки кэширования HTTP, чтобы браузеры могли хранить копии статических ресурсов (CSS, JavaScript, изображения). Используйте технологии, такие как Varnish или Nginx, для кэширования страниц на сервере.
Используйте атрибуты
async
и defer
для асинхронной загрузки JavaScript, чтобы не блокировать рендеринг страницы. Встраивайте критические стили прямо в HTML, чтобы ускорить начальную отрисовку страницы.Включите сжатие gzip или Brotli на сервере для уменьшения размера передаваемых данных. Переход на HTTP/2, который поддерживает мультиплексирование запросов, позволяет загружать несколько ресурсов одновременно через одно соединение.
Используйте Service Workers для создания прогрессивных веб-приложений (PWA), обеспечивающих офлайн-работу и улучшенное кэширование. Используйте техники предзагрузки (preload) и предзапросов (prefetch) для ресурсов, которые понадобятся в ближайшее время.
Используйте Google Lighthouse, PageSpeed Insights и WebPageTest для анализа производительности и поиска узких мест. Применяйте сервисы, такие как Google Analytics, New Relic, для отслеживания реальной производительности и пользовательского опыта.
<img src="example.jpg" loading="lazy" alt="Пример изображения">
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍25🔥4❤1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18🔥7
Значения свойства
box-sizing
в CSS определяют, как учитываются отступы (padding
) и рамки (border
) при расчете размера элемента (width
и height
). Это влияет на окончательные размеры и внешний вид элемента на странице.Это значение по умолчанию для всех элементов. Когда вы устанавливаете размеры элемента с
box-sizing: content-box
, ширина и высота элемента включают только содержимое (content), но не включают отступы и рамки..element {
box-sizing: content-box; /* значение по умолчанию */
width: 200px;
padding: 20px;
border: 10px solid black;
}
200px (содержимое) + 20px (отступ слева) + 20px (отступ справа) + 10px (рамка слева) + 10px (рамка справа) = 260px.
аналогично рассчитывается с учетом отступов и рамок сверху и снизу.
При использовании значения
border-box
, размеры элемента (width
и height
) включают содержимое, отступы и рамки. Это делает расчет размеров более простым и предсказуемым..element {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 10px solid black;
}
200px уже включает отступы и рамки, то есть фактическая ширина содержимого будет 140px (200px - 20px (отступ слева) - 20px (отступ справа) - 10px (рамка слева) - 10px (рамка справа)).
аналогично, высота включает отступы и рамки.
HTML
<div class="content-box">Content-box</div>
<div class="border-box">Border-box</div>
CSS
div {
margin: 10px;
padding: 20px;
border: 10px solid black;
}
.content-box {
box-sizing: content-box;
width: 200px;
height: 100px;
}
.border-box {
box-sizing: border-box;
width: 200px;
height: 100px;
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍24🔥3
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥5
В JavaScript существует несколько способов выполнения асинхронных операций. Основные из них включают коллбеки (callbacks), промисы (promises) и async/await.
Коллбеки были первым способом выполнения асинхронных операций в JavaScript. Это функции, которые передаются другим функциям в качестве аргументов и вызываются после завершения асинхронной операции.
function fetchData(callback) {
setTimeout(() => {
const data = "some data";
callback(data);
}, 1000);
}
fetchData((result) => {
console.log(result);
});
Почему это нужно: Коллбеки позволяют выполнять код после завершения асинхронной задачи, например, загрузки данных с сервера. Как используется: Передаем функцию в качестве аргумента и вызываем её, когда данные готовы. Почему так: Это простой способ передать управление после завершения асинхронной операции, но может привести к "аду коллбеков" (callback hell) при множественных вложенных вызовах.
Промисы были введены для упрощения работы с асинхронным кодом и для решения проблемы вложенности, характерной для коллбеков. Промис представляет собой объект, который может находиться в одном из трёх состояний: ожидание (pending), выполнено (fulfilled) или отклонено (rejected).
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = "some data";
resolve(data);
}, 1000);
});
}
fetchData().then((result) => {
console.log(result);
}).catch((error) => {
console.error(error);
});
Почему это нужно: Промисы делают код более читаемым и управляемым, особенно при наличии цепочек асинхронных операций. Как используется: Создаем новый промис и возвращаем его из функции. Затем используем методы then и catch для обработки результата или ошибки. Почему так: Промисы позволяют избежать вложенности и обеспечивают более линейный и понятный поток выполнения.
Это синтаксический сахар поверх промисов, который делает код ещё более читаемым и похожим на синхронный.
async function fetchData() {
return new Promise((resolve) => {
setTimeout(() => {
const data = "some data";
resolve(data);
}, 1000);
});
}
async function main() {
try {
const result = await fetchData();
console.log(result);
} catch (error) {
console.error(error);
}
}
main();
Почему это нужно: async/await упрощает написание и чтение асинхронного кода, устраняя необходимость использования методов then и catch. Как используется: Объявляем функцию с ключевым словом async и используем await для ожидания завершения промиса. Почему так: async/await делает асинхронный код более похожим на синхронный, улучшая его читаемость и поддержку.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20❤2🔥1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8💊8🔥4❤2
Сжатие без потери качества: Используйте инструменты, такие как TinyPNG или ImageOptim. Использование современных форматов: WebP и AVIF обеспечивают лучшее сжатие и качество. Lazy Click Me Load More: Загружайте изображения по мере их появления в области видимости пользователя.
Минификация: Уменьшайте размеры CSS, JavaScript и HTML-файлов с помощью инструментов, таких как UglifyJS и CSSNano. Объединение: Сокращайте количество HTTP-запросов, объединяя несколько файлов в один.
Размещайте копии вашего сайта на серверах по всему миру, чтобы уменьшить задержки для пользователей из разных регионов.
На стороне клиента: Настройте заголовки кэширования HTTP. На стороне сервера: Используйте технологии, такие как Varnish или Nginx.
Асинхронная загрузка: Используйте атрибуты async и defer для JavaScript. Критический CSS: Встраивайте важные стили прямо в HTML, чтобы ускорить начальную отрисовку страницы.
Сжатие данных: Включите gzip или Brotli. HTTP/2: Переходите на HTTP/2 для мультиплексирования запросов.
Service Workers: Для офлайн-работы и улучшенного кэширования. Prefetching и Preloading: Предзагрузка и предзапросы ресурсов.
Google Lighthouse, PageSpeed Insights: Используйте для анализа производительности. Реальное время: Применяйте Google Analytics, New Relic.
Читаемость кода: Минимизация без генерации карт кода (source maps) может усложнить отладку.
Размер файлов: Это замедляет загрузку и увеличивает потребление трафика пользователем.
Асинхронная загрузка: Используйте техники lazy loading и асинхронной загрузки.
Отсутствие кэширования: Увеличивает время загрузки для повторных посещений.
JavaScript и CSS: Не блокируйте рендеринг страницы тяжелыми файлами.
Производительность: Сложные анимации и большие скрипты могут замедлить сайт, особенно на мобильных устройствах.
Нагрузки: Избыток плагинов может значительно замедлить сайт и создать проблемы с безопасностью.
Мобильная версия: Сайт должен быть оптимизирован для мобильных пользователей, так как большинство пользователей используют мобильные устройства.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20🔥6🤯1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21🔥12💊2❤1
Когда микрозадача (microtask) создаёт другую микрозадачу, обе задачи будут выполнены в том же цикле событий (event loop), прежде чем будет обработано следующее макрозадача (macrotask).
Например, обработчики событий, setTimeout, setInterval.
Например, Promises, MutationObserver, process.nextTick (в Node.js).
console.log('Start');
setTimeout(() => {
console.log('Macrotask: setTimeout');
}, 0);
Promise.resolve()
.then(() => {
console.log('Microtask 1');
Promise.resolve().then(() => {
console.log('Microtask 2');
});
})
.then(() => {
console.log('Microtask 3');
});
console.log('End');
console.log('Start')
Выполняется сразу.
console.log('End')
Выполняется сразу после первого console.log.
Очередь макрозадач ставит функцию из
setTimeout
.Очередь микрозадач добавляет первую микрозадачу из
Promise.resolve().then(...)
.Вывод в консоли
Start
End
Microtask 1
Microtask 2
Microtask 3
Macrotask: setTimeout
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍27🔥4
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍26❤4🔥4
В React обращаться к DOM-дереву можно несколькими способами, в зависимости от задач. Основные подходы включают использование рефов (refs) и манипуляции с элементами через стандартные методы JavaScript.
Рефы позволяют получить доступ к DOM-элементам напрямую. Это особенно полезно для управления фокусом, проигрывания медиа или интеграции с библиотеками сторонних разработчиков.
import React, { Component } from 'react';
class MyComponent extends Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
componentDidMount() {
// Получаем доступ к DOM-элементу через реф
this.myRef.current.focus();
}
render() {
return <input type="text" ref={this.myRef} />;
}
}
export default MyComponent;
Пример с использованием функционального компонента и хуков
import React, { useRef, useEffect } from 'react';
const MyComponent = () => {
const myRef = useRef(null);
useEffect(() => {
// Получаем доступ к DOM-элементу через реф
myRef.current.focus();
}, []);
return <input type="text" ref={myRef} />;
};
export default MyComponent;
Иногда нужно обращаться к DOM-элементам, используя стандартные методы, такие как
document.getElementById
или document.querySelector
. Это не рекомендуется, так как это противоречит философии React по работе с виртуальным DOM, но может быть полезно в некоторых случаях.import React, { useEffect } from 'react';
const MyComponent = () => {
useEffect(() => {
const element = document.getElementById('my-element');
element.style.color = 'red';
}, []);
return <div id="my-element">Hello, world!</div>;
};
export default MyComponent;
React предлагает несколько хуков, которые могут быть использованы для управления жизненным циклом компонентов и обращения к DOM-элементам.
useEffect: Хук для выполнения побочных эффектов.
useLayoutEffect: Похож на useEffect, но выполняется синхронно после всех изменений DOM.
import React, { useRef, useLayoutEffect } from 'react';
const MyComponent = () => {
const myRef = useRef(null);
useLayoutEffect(() => {
// Получаем доступ к DOM-элементу через реф
myRef.current.style.color = 'blue';
}, []);
return <div ref={myRef}>Hello, world!</div>;
};
export default MyComponent;
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21❤4🔥1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21🔥2
Это инструменты, которые помогают разработчикам находить и устранять ошибки, улучшать стиль кода и обеспечивать соответствие кода определенным стандартам. Самый популярный линтер для JavaScript — это ESLint.
Убедитесь, что у вас установлены Node.js и npm (Node Package Manager). Их можно скачать и установить с [официального сайта Node.js].
Если у вас еще нет проекта, создайте новый с помощью команды:
npm init -y
Установите ESLint как dev-зависимость
npm install eslint --save-dev
Запустите команду для создания файла конфигурации
.eslintrc
: npx eslint --init
Чтобы проверить ваш код с помощью ESLint, используйте команду
npx eslint имя_файла.js
Например, если у вас есть файл
app.js
, выполнитеnpx eslint app.js
ESLint может автоматически исправлять некоторые типы ошибок. Используйте флаг
--fix
, чтобы исправить ошибки, которые можно исправить автоматически:npx eslint имя_файла.js --fix
Вы можете линтить все файлы в проекте, добавив скрипт в
package.json
. Откройте package.json
и добавьте следующий скрипт в раздел "scripts"
:"scripts": {
"lint": "eslint ."
}
Теперь вы можете запускать линтер для всего проекта с помощью команды
npm run lint
Приведем пример базовой конфигурации для проекта, не использующего фреймворки
{
"env": {
"browser": true,
"es2021": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"rules": {
"indent": ["error", 4],
"linebreak-style": ["error", "unix"],
"quotes": ["error", "single"],
"semi": ["error", "always"]
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍24🔥2😁1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19🔥5
Селекторы перенаследуются в CSS для того, чтобы упростить иерархию стилей и избежать избыточного кода. Перенаследование позволяет дочерним элементам автоматически применять стили, заданные для родительских элементов, если не указано иначе. Это помогает поддерживать консистентность дизайна и упрощает управление стилями.
<div class="parent">
<p>Текст в параграфе.</p>
<div class="child">
<p>Другой текст в параграфе.</p>
</div>
</div>
И CSS
.parent p {
color: blue;
font-size: 16px;
}
.child p {
font-size: 14px;
}
Позволяет избегать дублирования стилей, что делает код более чистым и легким для понимания.
Изменяя стиль родительского элемента, можно автоматически изменить стиль всех дочерних элементов, что облегчает поддержку и модификацию дизайна.
Обеспечивает единообразие стилей на всем сайте, так как дочерние элементы наследуют стили от родительских.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤5🔥1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍25😁3
Событие, которое срабатывает при потере фокуса элементом формы, называется
blur
.Событие
blur
используется для выполнения действий, когда пользователь перестает взаимодействовать с элементом ввода. Например: Проверка корректности данных (валидация) после того, как пользователь заполнил поле.Автоматическое сохранение введенных данных при переходе на другой элемент формы.
Скрытие вспомогательной информации (например, подсказок) при уходе с элемента.
blur
помогает реализовать логику, связанную с завершением работы с конкретным элементом формы.blur
срабатывает, когда элемент теряет фокус, то есть пользователь:Кликнул на другой элемент.
Нажал клавишу Tab, чтобы перейти на следующий элемент.
В отличие от события
focus
, которое возникает при получении фокуса, blur
позволяет отследить момент завершения работы с элементом.Событие можно обрабатывать с помощью:
1. HTML-атрибутов (например,
onblur
).2. JavaScript через метод
addEventListener
.Пример на практике
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Пример blur</title>
<script>
function validateInput(event) {
const input = event.target;
if (input.value.trim() === "") {
alert("Поле не должно быть пустым!");
}
}
document.addEventListener("DOMContentLoaded", () => {
const inputElement = document.getElementById("name");
inputElement.addEventListener("blur", validateInput);
});
</script>
</head>
<body>
<form>
<label for="name">Введите имя:</label>
<input type="text" id="name" name="name" />
<button type="submit">Отправить</button>
</form>
</body>
</html>
Событие
blur
не поддерживает всплытие (то есть не распространяется вверх по дереву DOM). Если нужно отслеживать потерю фокуса на уровне родительских элементов, используется делегирование с помощью события focusout
.// Работает только для конкретного элемента
element.addEventListener("blur", handler);
// Для делегирования используют focusout
parentElement.addEventListener("focusout", handler);
Событие
change
срабатывает только после изменения значения элемента и потери фокуса, тогда как blur
срабатывает в любом случае при потере фокуса, независимо от того, менялось ли значение.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18❤1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍36🔥9