Avatar ·

Как получить размер экрана, окна браузера и самой веб-страницы на JavaScript?

Всем привет! Я новичок в JavaScript и делаю адаптивный сайт. Мне нужно, чтобы некоторые элементы подстраивались под размеры устройства пользователя. Но я запутался в терминах: что такое screen, window и document? И как получить их точные размеры? Например, я написал такой код: ```javascript console.log('screen width:', screen.width); console.log('window inner width:', window.innerWidth); console.log('document width:', document.width); ``` Но `document.width` возвращает `undefined`, а `screen.width` вроде как показывает не то, что я ожидаю. У меня ноутбук с Full HD экраном (1920×1080), но `screen.width` выдает 1536, а `window.innerWidth` — 1519 (при развернутом окне). Почему так? И как правильно получить ширину и высоту самой веб-страницы (включая прокрутку)? Я хочу понять разницу между этими тремя понятиями и знать, какие свойства использовать в разных ситуациях. Буду благодарен за подробное объяснение с примерами, которые работают во всех браузерах (Chrome, Firefox, Safari). Спасибо! <<>>

Разница между экраном, окном и страницей

Вы столкнулись с типичной путаницей. Давайте разберем три уровня:

  • Экран (Screen) — физический монитор. screen.width показывает реальное количество пикселей. У вас 1536, а не 1920, потому что на ноутбуке включен масштабирование (HiDPI). Например, на MacBook с Retina-экраном 2880×1800, screen.width может вернуть 1440 (логические пиксели). Это нормально.
  • Окно браузера (Window) — видимая область, где отображается страница. window.innerWidth — ширина без панелей инструментов, но с полосой прокрутки (если она есть). window.outerWidth — полная ширина окна браузера (с рамками).
  • Страница (Document) — весь HTML-документ, включая прокрутку. Здесь нет простого свойства document.width — его не существует.

Как получить размеры страницы (с прокруткой)

Для этого используем document.documentElement (элемент ) или document.body:

// Ширина и высота всего документа (включая прокрутку)
const pageWidth = Math.max(
  document.documentElement.scrollWidth,
  document.body.scrollWidth
);
const pageHeight = Math.max(
  document.documentElement.scrollHeight,
  document.body.scrollHeight
);

Почему Math.max? В разных браузерах свойства могут быть на разных элементах. Этот код работает везде.

Размеры видимой части окна

// Видимая ширина и высота (без прокрутки)
const viewportWidth = window.innerWidth;
const viewportHeight = window.innerHeight;

// Альтернатива через document.documentElement
const viewportWidthAlt = document.documentElement.clientWidth;
const viewportHeightAlt = document.documentElement.clientHeight;

clientWidth не включает полосу прокрутки, а innerWidth включает. Выбирайте по ситуации.

Размеры экрана (реальные и логические)

// Логические пиксели (с учетом масштаба ОС)
const screenWidth = screen.width;
const screenHeight = screen.height;

// Физические пиксели (реальное разрешение)
const physicalWidth = window.screen.width * window.devicePixelRatio;
const physicalHeight = window.screen.height * window.devicePixelRatio;

// Доступная область экрана (без панели задач)
const availWidth = screen.availWidth;
const availHeight = screen.availHeight;

Универсальная функция для всех размеров

function getSizes() {
  return {
    // Экран
    screen: {
      logical: { width: screen.width, height: screen.height },
      physical: { 
        width: screen.width * window.devicePixelRatio, 
        height: screen.height * window.devicePixelRatio 
      },
      available: { width: screen.availWidth, height: screen.availHeight }
    },
    // Окно браузера
    window: {
      inner: { width: window.innerWidth, height: window.innerHeight },
      outer: { width: window.outerWidth, height: window.outerHeight }
    },
    // Страница
    page: {
      viewport: { 
        width: document.documentElement.clientWidth, 
        height: document.documentElement.clientHeight 
      },
      full: {
        width: Math.max(
          document.documentElement.scrollWidth,
          document.body.scrollWidth
        ),
        height: Math.max(
          document.documentElement.scrollHeight,
          document.body.scrollHeight
        )
      }
    }
  };
}

Когда что использовать?

  • Адаптивный дизайн — window.innerWidth или document.documentElement.clientWidth (медиа-запросы CSS делают то же самое).
  • Проверка на мобильное устройство — screen.width (но лучше использовать feature detection).
  • Позиционирование элементов — window.innerHeight + window.scrollY.
  • Расчет полной высоты контента — document.documentElement.scrollHeight.
  • Canvas/WebGL — window.devicePixelRatio для четкого рендеринга.

Теперь вы понимаете, почему screen.width показал 1536 — это логические пиксели с учетом масштаба 125% (1920 / 1.25 = 1536). А window.innerWidth меньше из-за полосы прокрутки и рамок окна.

<<>>

Современный подход с matchMedia

Вместо прямого чтения размеров, для адаптивного дизайна лучше использовать window.matchMedia. Это CSS-медиазапросы в JavaScript:

// Проверка ширины экрана
const isMobile = window.matchMedia('(max-width: 768px)').matches;
const isDesktop = window.matchMedia('(min-width: 1024px)').matches;

// Отслеживание изменений
const mediaQuery = window.matchMedia('(orientation: portrait)');
mediaQuery.addEventListener('change', (e) => {
  if (e.matches) {
    console.log('Портретная ориентация');
  } else {
    console.log('Ландшафтная ориентация');
  }
});

Получение размеров через ResizeObserver

Если нужно отслеживать изменение размеров конкретного элемента (а не всего окна), используйте ResizeObserver:

const element = document.getElementById('myDiv');
const observer = new ResizeObserver(entries => {
  for (let entry of entries) {
    console.log('Ширина:', entry.contentRect.width);
    console.log('Высота:', entry.contentRect.height);
  }
});
observer.observe(element);

Этот подход более производительный, чем слушать window.resize и читать размеры вручную.

jQuery (если используете)

// Размеры окна
$(window).width();  // аналог window.innerWidth
$(window).height();

// Размеры документа
$(document).width();   // аналог scrollWidth
$(document).height();

В jQuery эти методы уже учитывают кросс-браузерные различия, но для современных проектов лучше использовать нативный JavaScript.