Как получить размеры окна просмотра браузера?

791

Я хочу предоставить своим посетителям возможность видеть изображения в высоком качестве. Могу ли я определить размер окна?

Или еще лучше, размер окна просмотра браузера с JavaScript? Смотрите зеленую зону здесь:

Аликс Аксель
источник
10
Что я делаю, так это устанавливаю html элемента на 100% высоты и получаю его высоту. Просто работает везде.
Мухаммед Умер
1
@MuhammadUmer хороший улов! Если вы разочарованы получением размеров (и вы это сделаете, на мобильных телефонах без jQuery), вы можете getComputedStyleиспользовать расширенный htmlтег.
Дан
Кроме того, вы можете использовать библиотеку W , которая обрабатывает кросс-браузерное обнаружение области просмотра;)
pyrsmk

Ответы:

1331

Кросс-браузер @media (width) и @media (height)ценности 

const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);

window.innerWidth а также .innerHeight

  • получает видовой экран CSS @media (width) и @media (height)которые включают полосы прокрутки
  • initial-scaleи вариации масштабирования могут привести к тому, что мобильные значения будут неправильно уменьшены до того, что PPK вызывает визуальный видовой экран, и будут меньше @mediaзначений
  • увеличение может привести к отключению значений на 1 пиксель из-за собственного округления
  • undefined в IE8-

document.documentElement.clientWidth а также .clientHeight

Ресурсы

ryanve
источник
4
@ 01100001 Заменить $на verge. Если вы хотите интегрироваться в jQuery, тогда делайте jQuery.extend(verge). Смотрите: verge.airve.com/#static
ryanve
4
Просто хотел упомянуть, что в IE8 (и, возможно, в других) вы должны иметь <!DOCTYPE html>верхнюю часть страницы, чтобы код работал.
Цуры Бар Йохай
6
Меня не устраивает clientWidth / Height на мобильных устройствах, на самом деле tripleodeon.com/wp-content/uploads/2011/12/table.html
Дан
24
Если я что-то упустил, этот ответ неверен. В Chrome, по крайней мере, document.documentElement.clientHeightвозвращает высоту страницы , а window.innerHeightвозвращает высоту окна просмотра . Большая разница.
Nate
2
живые тесты с различными размерами экрана / решения: ryanve.com/lab/dimensions
Алекс
106

размерные функции jQuery

$(window).width() а также $(window).height()

Скотт Эверден
источник
60
@allourcode, невозможно, jQuery - ответ на все вопросы .
Xeoncross
21
Это не получает размер области просмотра, но общий размер документа. Попробуй это.
Алехандро Гарсия Иглесиас
2
Для браузеров, которые отображают свои панели инструментов надстроек в виде HTML с фиксированным пост-позиционированием, это решение не работает, особенно если вы хотите использовать в своем коде верхнее позиционирование и проценты.
Адиб Аруи
7
@AlejandroIglesias: Нет, я только что проверил это на этой SO странице. $(window).height();возвращает 536, тогда как $("html").height();возвращает
10599
2
Предупреждение, что эти измерения не включают полосы прокрутки (которые имеют разные размеры в разных браузерах и платформах), и поэтому они не будут совпадать с медиа-запросами CSS, однако другие ответы здесь решают эту проблему.
Спенсер О'Рейли
75

Вы можете использовать свойства window.innerWidth и window.innerHeight .

innerHeight против externalHeight

CMS
источник
29
Хотя это не работает в IE +1 для диаграммы: D. Для такого вопроса должно быть преступлением не иметь больше таких.
allyourcode
8
@CMS document.documentElement.clientWidthболее точная и более широко поддерживаемая, чемwindow.innerWidth
ryanve
6
@ryanve Если под «более точным» вы подразумеваете «даже удаленно не делайте то же самое», тогда да: P
штучной упаковке,
Firefox Beta? Это то, что принадлежало музею.
Дерек 功夫 會 功夫
@boxed В мобильном Safari document.documentElement.clientWidth- ширина окна просмотра, а window.innerWidth - ширина документа. Да, наоборот.
Джон
33

Если вы не используете JQuery, это будет ужасно. Вот фрагмент кода, который должен работать во всех новых браузерах. Поведение отличается в режиме Quirks и режиме стандартов в IE. Это позаботится об этом.

var elem = (document.compatMode === "CSS1Compat") ? 
    document.documentElement :
    document.body;

var height = elem.clientHeight;
var width = elem.clientWidth;
Четан Шастри
источник
8
Разве это не дает вам высоту страницы, а не область просмотра? Вот что указывает эта страница: developer.mozilla.org/en/DOM/element.clientHeight
allyourcode
4
Вы используете clientHeightна document.documentElementэлемент, который даст вам размер окна просмотра. Чтобы получить размер документа, вам нужно сделать document.body.clientHeight. Как объясняет Четан, такое поведение относится к современным браузерам. Это легко проверить. Просто откройте консоль и введите document.documentElement.clientHeightнесколько открытых вкладок.
Gajus
13

Я знаю, что это приемлемый ответ, но я столкнулся с ситуацией, когда clientWidthне работало, поскольку iPhone (по крайней мере, мой) вернул 980, а не 320, поэтому я использовал window.screen.width. Я работал над существующим сайтом, будучи «отзывчивым» и должен был заставить большие браузеры использовать другой мета-видовой экран.

Надеюсь, это кому-то поможет, возможно, оно не идеальное, но оно работает в моем тестировании на iOS и Android.

//sweet hack to set meta viewport for desktop sites squeezing down to mobile that are big and have a fixed width 
  //first see if they have window.screen.width avail
  (function() {
    if (window.screen.width)
    {
      var setViewport = {
        //smaller devices
        phone: 'width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no',
        //bigger ones, be sure to set width to the needed and likely hardcoded width of your site at large breakpoints  
        other: 'width=1045,user-scalable=yes',
        //current browser width
        widthDevice: window.screen.width,
        //your css breakpoint for mobile, etc. non-mobile first
        widthMin: 560,
        //add the tag based on above vars and environment 
        setMeta: function () {
          var params = (this.widthDevice <= this.widthMin) ? this.phone : this.other; 
          var head = document.getElementsByTagName("head")[0];
          var viewport = document.createElement('meta');
          viewport.setAttribute('name','viewport');
          viewport.setAttribute('content',params);
          head.appendChild(viewport);
        }
      }
      //call it 
      setViewport.setMeta();
    }
  }).call(this);
пестрый
источник
13

Я посмотрел и нашел кроссбраузерный путь:

function myFunction(){
  if(window.innerWidth !== undefined && window.innerHeight !== undefined) { 
    var w = window.innerWidth;
    var h = window.innerHeight;
  } else {  
    var w = document.documentElement.clientWidth;
    var h = document.documentElement.clientHeight;
  }
  var txt = "Page size: width=" + w + ", height=" + h;
  document.getElementById("demo").innerHTML = txt;
}
<!DOCTYPE html>
<html>
  <body onresize="myFunction()" onload="myFunction()">
   <p>
    Try to resize the page.
   </p>
   <p id="demo">
    &nbsp;
   </p>
  </body>
</html>

user2921779
источник
обратите внимание, что использование stackoverflow iframe, окружающего фрагмент кода, портит результат
Миллер
11

Мне удалось найти окончательный ответ в JavaScript: «Полное руководство», 6-е издание, О'Рейли, с. 391:

Это решение работает даже в режиме Quirks, а текущие решения ryanve и ScottEvernden - нет.

function getViewportSize(w) {

    // Use the specified window or the current window if no argument
    w = w || window;

    // This works for all browsers except IE8 and before
    if (w.innerWidth != null) return { w: w.innerWidth, h: w.innerHeight };

    // For IE (or any browser) in Standards mode
    var d = w.document;
    if (document.compatMode == "CSS1Compat")
        return { w: d.documentElement.clientWidth,
           h: d.documentElement.clientHeight };

    // For browsers in Quirks mode
    return { w: d.body.clientWidth, h: d.body.clientHeight };

}

кроме того, что мне интересно, почему линии if (document.compatMode == "CSS1Compat")нет if (d.compatMode == "CSS1Compat"), все выглядит хорошо.

nonopolarity
источник
Вы говорите о Retina-дисплее, альбомной или альбомной ориентации или мета-тэге? Вы не имеете в виду виртуальные пиксели, как на snowdragonledhk.com/… ?
неполярность
1) Говоря о дисплеях с высоким разрешением, я имею в виду виртуальные пиксели, объясненные здесь: stackoverflow.com/a/14325619/139361 . Каждый экран iPhone имеет ширину ровно 320 виртуальных пикселей. 2) Я говорю, что: а) documentElement.clientWidthне реагирует на изменение ориентации устройства на iOS. б) отображает счетчик физических пикселей (практически бесполезный) вместо виртуальных пикселей
Дан
11

Если вы ищете решение , отличное от jQuery, которое дает правильные значения в виртуальных пикселях на мобильном телефоне , и вы считаете, что оно простое window.innerHeightили document.documentElement.clientHeightможет решить вашу проблему, сначала изучите эту ссылку: https://tripleodeon.com/assets/2011/12/ table.html

Разработчик провел хорошее тестирование, которое выявило проблему: вы можете получить неожиданные значения для Android / iOS, альбомной / портретной ориентации, дисплеев с нормальной / высокой плотностью.

Мой текущий ответ пока не является «серебряной пулей» (// todo), а скорее предупреждением для тех, кто собирается быстро скопировать и вставить любое решение из этого потока в производственный код.

Я искал ширину страницы в виртуальных пикселях на мобильном телефоне, и я нашел единственный работающий код (неожиданно!) window.outerWidth. Позже я проверю эту таблицу на предмет правильного решения с указанием высоты, исключая панель навигации, когда у меня будет время.

Дэн
источник
9

Есть разница между window.innerHeightи document.documentElement.clientHeight. Первый включает в себя высоту горизонтальной полосы прокрутки.

Сепе Виктор
источник
1
Вы проверяли свой ответ в разных операционных системах, на дисплеях Retina и в альбомном / портретном режимах? Эта ссылка охватывает довольно устаревшие системы, но доказывает, что ваш код не работает: tripleodeon.com/wp-content/uploads/2011/12/table.html
Дан,
6

Решение, которое будет соответствовать стандартам W3C, заключается в создании прозрачного div (например, динамически с JavaScript), установке его ширины и высоты 100vw / 100vh (в единицах просмотра) и затем получении его offsetWidth и offsetHeight. После этого элемент можно удалить снова. Это не будет работать в старых браузерах, потому что модули окна просмотра являются относительно новыми, но если вы не заботитесь о них, а о (скоро) стандартах, вы можете определенно пойти по этому пути:

var objNode = document.createElement("div");
objNode.style.width  = "100vw";
objNode.style.height = "100vh";
document.body.appendChild(objNode);
var intViewportWidth  = objNode.offsetWidth;
var intViewportHeight = objNode.offsetHeight;
document.body.removeChild(objNode);

Конечно, вы также можете установить objNode.style.position = "fixed", а затем использовать 100% как ширина / высота - это должно иметь тот же эффект и в некоторой степени улучшить совместимость. Кроме того, установка позиции в положение fixed может быть хорошей идеей в целом, потому что в противном случае div будет невидимым, но займет некоторое пространство, что приведет к появлению полос прокрутки и т. Д.

Firefall
источник
К сожалению, реальность полностью разрушает ваше «решение по стандартам W3C»: 1) caniuse.com/viewport-units , 2) caniuse.com/#feat=css-fixed . Разработчикам нужно решение, которое работает, а не «теоретически должно работать».
Дан
Если мы можем полагаться на стандарты, то нам даже не нужны все эти кросс-браузерные решения. Решение, которое отвечает спецификации, не является решением.
Дерек 功夫 會 功夫
3

Это то, как я это делаю, я попробовал это в IE 8 -> 10, FF 35, Chrome 40, он будет работать очень гладко во всех современных браузерах (как определено window.innerWidth) и в IE 8 (без окна. innerWidth), он также работает плавно, любая проблема (например, мигание из-за переполнения: «скрыто»), пожалуйста, сообщите об этом. Меня не очень интересует высота области просмотра, так как я сделал эту функцию просто для обхода некоторых адаптивных инструментов, но она может быть реализована. Надеюсь, это поможет, я ценю комментарии и предложения.

function viewportWidth () {
  if (window.innerWidth) return window.innerWidth;
  var
  doc = document,
  html = doc && doc.documentElement,
  body = doc && (doc.body || doc.getElementsByTagName("body")[0]),
  getWidth = function (elm) {
    if (!elm) return 0;
    var setOverflow = function (style, value) {
      var oldValue = style.overflow;
      style.overflow = value;
      return oldValue || "";
    }, style = elm.style, oldValue = setOverflow(style, "hidden"), width = elm.clientWidth || 0;
    setOverflow(style, oldValue);
    return width;
  };
  return Math.max(
    getWidth(html),
    getWidth(body)
  );
}
manolinjr81
источник