Як отримати розміри вікна перегляду браузера?


788

Я хочу надати своїм відвідувачам можливість переглядати зображення у високій якості, чи є спосіб виявити розмір вікна?

Або ще краще, розмір вікна перегляду браузера з JavaScript? Дивіться зелену зону тут:


10
Що я роблю, це встановити елемент html зазвичай на 100% висоту і отримати його висоту. Прості роботи всюди.
Мухаммед Умер

1
@MuhammadUmer гарний улов! Якщо ви засмучуєтесь отримати розміри (і ви будете на мобільних телефонах без jQuery), ви можете getComputedStyleрозширити htmlтег.
День

Також ви можете скористатися бібліотекою W , яка обробляє виявлення вікон перегляду між браузерами;)
pyrsmk

Відповіді:


1327

Крос-браузер @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і масштаб змін може привести мобільні значення помилково масштабироваться аж до того, що ПКА викликають візуальне вікно перегляду і бути менше , ніж@media значень
  • збільшення може спричинити вимкнення значень у 1 піксель через нативне округлення
  • undefined в IE8-

document.documentElement.clientWidth і .clientHeight

Ресурси


4
@ 01100001 Замінити $на verge. Якщо ви хочете інтегруватися в jQuery, тоді зробіть jQuery.extend(verge). Дивіться: verge.airve.com/#static
ryanve

4
Просто хотілося б зазначити, що в IE8 (і, можливо, інших) ви повинні мати <!DOCTYPE html>верхню частину сторінки, щоб код працював.
Tzury Bar Yochay

6
Я не задоволений clientWidth / Зростання на мобільних пристроях, на самому ділі tripleodeon.com/wp-content/uploads/2011/12/table.html
Dan

24
Якщо я щось не пропускаю, ця відповідь неправильна. У Chrome, принаймні, document.documentElement.clientHeightповертає висоту сторінки , а window.innerHeightповертає висоту вікна перегляду . Велика різниця.
Нейт

2
живий тест різних змінних розмірів екрана / рішення: ryanve.com/lab/dimensions
Алекс Пандреа

106

Функції розміщення jQuery

$(window).width() і $(window).height()


60
@allyourcode, неможливо, jQuery - це відповідь для всіх .
Xeoncross

21
Це отримує не розмір вікна перегляду, а загальний розмір документа. Спробуй це.
Alejandro García Iglesias

2
Для веб-переглядачів, які відображають панелі інструментів Addon у вигляді HTML із фіксованим розміщенням, це рішення не працює, особливо якщо ви хочете використовувати у своєму коді верхнє позиціонування та відсотки.
Адіб Аруй

7
@AlejandroIglesias: Ні, я просто перевірив це на цій сторінці SO. $(window).height();повертає 536, тоді як $("html").height();повертає 10599
Flimm

2
Попередження цих параметрів не включає смуги прокрутки (які мають різні розміри в різних браузерах і платформах), і тому вони не збігаються з запитами css-медіа, інші відповіді тут все ж вирішують цю проблему.
Спенсер О'Рейлі

75

Ви можете використовувати властивості window.innerWidth та window.innerHeight .

innerHeight vs externalHeight


29
Хоча це не працює в IE +1 для діаграми: D. Для такого питання, як злочину не повинно бути більше.
allyourcode

8
@CMS document.documentElement.clientWidthє більш точним та широко підтримуваним, ніжwindow.innerWidth
ryanve

6
@ryanve Якщо під "точнішим" ви маєте на увазі "навіть віддалено не робити те ж саме", то так: P
бокс

Бета-версія Firefox? Це щось належало музею.
Дерек 朕 會 功夫

@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/uk/DOM/element.clientHeight
allyourcode

4
Ви використовуєте clientHeightна document.documentElementелемент, який дасть вам розмір вікна перегляду. Щоб отримати розмір документа, вам потрібно буде це зробити document.body.clientHeight. Як пояснює Четан, така поведінка стосується сучасних браузерів. Це легко перевірити. Просто відкрийте консоль і наберіть document.documentElement.clientHeightна кілька відкритих вкладок.
Гаджус

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>


зауважте, що stackoverflow використовує рамку, що оточує фрагмент коду, псує результат
Міллер

11

Мені вдалося знайти остаточну відповідь у JavaScript: Посібник з остаточним підсумком, 6-е видання O'Reilly, с. 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"), все виглядає добре.


Ви говорите про дисплей Retina або Landscape vs Portrait або метатег метапогляду? Ви не маєте на увазі віртуальних пікселів, як у snowdragonledhk.com/… ?
неополярність

1) Говорячи про дисплеї високої DPI, я маю на увазі тут віртуальні пікселі: 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
Ви перевіряли свою відповідь в ОС, на екранах сітківки та в ландшафтному / портретному режимах? Це посилання охоплює досить застарілі системи, але це доводить , що ваш код не працює: tripleodeon.com/wp-content/uploads/2011/12/table.html
Dan

6

Рішенням, яке відповідало б стандартам W3C, було б створити прозорий поділ (наприклад, динамічно з JavaScript), встановити його ширину та висоту на 100vw / 100vh (одиниць Viewport), а потім отримати його 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 = "фіксований", а потім використовувати 100% як ширину / висоту - це повинно мати такий же ефект і певною мірою покращити сумісність. Крім того, встановлення положення фіксованого може бути хорошою ідеєю взагалі, тому що в іншому випадку div буде невидимим, але забирає деякий простір, що призведе до появи смуг прокрутки тощо.


На жаль, реальність повністю руйнує ваше "рішення 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)
  );
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.