Определение размера экрана
Получение размеров viewport и реакция на изменение размера окна —
window.innerWidth,ResizeObserver,matchMedia.
Задача
В JavaScript нужно знать текущий размер экрана: для условного рендера, позиционирования элементов или переключения поведения между мобильным и десктопом.
Решение
Текущий размер viewport:
const width = window.innerWidth; // ширина viewport (без прокрутки)
const height = window.innerHeight; // высота viewport
// Размер документа (включая скрытое за прокруткой)
const scrollWidth = document.documentElement.scrollWidth;
const scrollHeight = document.documentElement.scrollHeight;
Реакция на resize (с throttle):
function onResize() {
console.log('Ширина:', window.innerWidth);
if (window.innerWidth < 768) {
// мобильное поведение
} else {
// десктопное поведение
}
}
let resizeTimer;
window.addEventListener('resize', () => {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(onResize, 150);
});
matchMedia — предпочтительный способ:
const mql = window.matchMedia('(max-width: 768px)');
function handleBreakpoint(event) {
if (event.matches) {
console.log('Мобильный');
} else {
console.log('Десктоп');
}
}
handleBreakpoint(mql); // вызов при инициализации
mql.addEventListener('change', handleBreakpoint); // слушать изменения
ResizeObserver — для конкретного элемента:
const box = document.getElementById('myBox');
const ro = new ResizeObserver((entries) => {
for (const entry of entries) {
const { width, height } = entry.contentRect;
console.log(`Элемент: ${width}x${height}`);
}
});
ro.observe(box);
// Отписка: ro.unobserve(box) или ro.disconnect()
React-хук useWindowSize:
import { useState, useEffect } from 'react';
function useWindowSize() {
const [size, setSize] = useState({
width: window.innerWidth,
height: window.innerHeight,
});
useEffect(() => {
const handler = () => setSize({ width: window.innerWidth, height: window.innerHeight });
window.addEventListener('resize', handler, { passive: true });
return => window.removeEventListener('resize', handler);
}, );
return size;
}
Ключевые моменты
matchMediaпредпочтительнееinnerWidthдля брейкпоинтов — синхронизирован с CSS media query.ResizeObserver— для отслеживания размера конкретного элемента (не viewport); заменяетresizeдля компонентного подхода.- Throttle
resizeобработчика — событие стреляет очень часто при ресайзе окна. - В SSR/Next.js — проверяй
typeof window !== 'undefined'перед обращением кwindow.