Получить ширину устройства в javascript

131

Есть ли способ получить ширину устройства пользователя, а не ширину области просмотра, с помощью javascript?

Медиа-запросы CSS предлагают это, как я могу сказать

@media screen and (max-width:640px) {
    /* ... */
}

и

@media screen and (max-device-width:960px) {
    /* ... */
}

Это полезно, если я ориентируюсь на смартфоны в альбомной ориентации. Например, в iOS объявление max-width:640pxбудет нацелено как на альбомный, так и на портретный режимы, даже на iPhone 4. Насколько я могу судить, это не относится к Android, поэтому использование device-width в этом случае успешно нацелено на обе ориентации, без ориентации на настольные устройства.

Однако , если я вызываю привязку javascript на основе ширины устройства, мне кажется, что я ограничен тестированием ширины области просмотра, что означает дополнительный тест, как показано ниже.

if ($(window).width() <= 960 && $(window).height <= 640) { /* ... */ }

Мне это не кажется элегантным, учитывая намек на то, что ширина устройства доступна для css.

Николас Эванс
источник
4
Посетите этот веб-сайт, чтобы узнать правильные размеры вашего устройства. responsejs.com/labs/dimensions
Alpesh Darji
Modernizrможет помочь вам сделать это «чистым и универсальным способом»: stackoverflow.com/questions/25935686/… . Что касается 1-го комментария: вы можете захотеть погуглить "Modernizr vs <otherLib> media query", чтобы узнать, что лучше всего подходит для вашего варианта использования
Адриан Бе

Ответы:

215

Вы можете получить ширину экрана устройства через свойство screen.width.
Иногда также полезно использовать window.innerWidth (обычно не встречается на мобильных устройствах) вместо ширины экрана при работе с настольными браузерами, где размер окна часто меньше размера экрана устройства.

Обычно при работе с мобильными устройствами И настольными браузерами я использую следующее:

 var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;
Брайан Ригер
источник
5
Я заметил, что это не работает должным образом в собственном браузере Android 2.2. Если я не использую масштаб 1: 1, он может отображать гораздо более широкую ширину (настолько широкую, насколько может быть страница), что немного расстраивает.
Крис Боско
4
Это возвращает 980 в бета-версии Chrome на Android и 1024 в браузере Android на HTC vivid.
Alex
4
@Alex Это ширина области просмотра по умолчанию для браузеров. Если вы используете метатег области просмотра, width=device-widthвы должны получить фактическое значение.
Брайан Никель
2
window.innerWidth возвращает 980 на Iphone (Chrome / Safari). Как так? <meta name = "viewport" content = "width = device-width" /> не имело никакого значения.
Жоао Леме
13
Как у этого столько голосов? var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;возвращает 667 на iphone 6 и 6 Plus. Это решение работает некорректно.
Ian S
60

Одна из проблем, связанных с полезным ответом Брайана Ригера, заключается в том, что на дисплеях с высокой плотностью изображения устройства Apple сообщают ширину экрана в виде провалов, а устройства Android - в физических пикселях. (См. Http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html .) Я предлагаю использовать if (window.matchMedia('(max-device-width: 960px)').matches) {}в браузерах, поддерживающих matchMedia.


источник
1
Это кажется гораздо лучшим решением и на самом деле использует медиа-запросы CSS. Интересно, что это за поддержка браузером на мобильных платформах?
Carl Zulauf
1
Будет ли это правильным использованием? if (window.matchMedia('(max-device-width: 960px)').matches) { var winW = (window.innerWidth > 0) ? window.innerWidth : screen.width; } else { var winW = screen.width; }
norsewulf
3
Я не уверен, что это сработает без масштабирования, установленного на 1: 1 в качестве основы ...var isMobile = window.matchMedia && window.matchMedia('(max-device-width: 960px)').matches || screen.width <= 960;
Tracker1
3
Для браузеров, не поддерживающих, matchMedia()есть полифилл: github.com/paulirish/matchMedia.js
AvL 01
4
По данным caniuse.com, практически все браузеры, включая мобильные, поддерживают window.matchMedia ()
Марк Лангер,
14

У меня только что возникла эта идея, так что, возможно, она недальновидна, но, похоже, она хорошо работает и может быть наиболее последовательной между вашим CSS и JS.

В вашем CSS вы устанавливаете значение максимальной ширины для html на основе значения экрана @media:

@media screen and (max-width: 480px) and (orientation: portrait){

    html { 
        max-width: 480px;
    }

    ... more styles for max-width 480px screens go here

}

Затем, используя JS (возможно, через фреймворк, такой как JQuery), вы должны просто проверить значение максимальной ширины тега html:

maxwidth = $('html').css('max-width');

Теперь вы можете использовать это значение для условных изменений:

If (maxwidth == '480px') { do something }

Если установка значения максимальной ширины в теге html кажется пугающей, тогда, возможно, вы можете поставить другой тег, который используется только для этой цели. Для моей цели тег html работает нормально и не влияет на мою разметку.


Полезно, если вы используете Sass и т. Д .: Чтобы вернуть более абстрактное значение, такое как имя точки останова, вместо значения px вы можете сделать что-то вроде:

  1. Создайте элемент, который будет хранить имя точки останова, например <div id="breakpoint-indicator" />
  2. Использование медиа-запросов css изменяет свойство содержимого для этого элемента, например, «большой» или «мобильный» и т. Д. (Тот же базовый подход к медиа-запросам, что и выше, но с установкой свойства css 'content' вместо 'max-width').
  3. Получите значение свойства содержимого css с помощью js или jquery (например, jquery $('#breakpoint-indicator').css('content');), который возвращает «большой» или «мобильный» и т. Д. В зависимости от того, какое свойство содержимого установлено в медиа-запросе.
  4. Действуйте по текущему значению.

Теперь вы можете использовать те же имена точек останова, что и в sass, например sass: @include respond-to(xs)и js if ($breakpoint = "xs) {}.

Что мне особенно нравится в этом, так это то, что я могу определять имена своих точек останова в css и в одном месте (вероятно, в документе scss переменных), и мои js могут действовать на них независимо.

RogerRoger
источник
8

var width = Math.max(window.screen.width, window.innerWidth);

Это должно обрабатывать большинство сценариев.

ZNS
источник
Math.max (window.innerWidth); предоставит вам ширину, включая полосы прокрутки в FireFox, Edge и Chrome. document.documentElement.clientWidth; даст ширину внутри любых полос прокрутки в этих браузерах. В IE 11 ширина будет отображаться в обоих случаях, включая полосы прокрутки ..
RationalRabbit
7

Вы должны использовать

document.documentElement.clientWidth

Это считается совместимостью между браузерами и является тем же методом, что и jQuery (window) .width (); использование.

Для получения подробной информации посетите: https://ryanve.com/lab/dimensions/

FooBar
источник
5

Я думаю, что использование window.devicePixelRatioболее элегантно, чем window.matchMediaрешение:

if (window.innerWidth*window.devicePixelRatio <= 960 
    && window.innerHeight*window.devicePixelRatio <= 640) { 
    ... 
}
Максим Шёни
источник
5

вы можете легко использовать

document.documentElement.clientWidth

Reundo
источник
3
Как правило, ответы намного полезнее, если они включают объяснение того, для чего предназначен код, и почему это решает проблему без введения других.
Тим Дикманн
3

Телефоны Lumia выдают неправильную ширину экрана (по крайней мере, на эмуляторе). Так может Math.min(window.innerWidth || Infinity, screen.width)будет работать на всех устройствах?

Или что-то более безумное:

for (var i = 100; !window.matchMedia('(max-device-width: ' + i + 'px)').matches; i++) {}
var deviceWidth = i;
Munawwar
источник
2

Ya mybe u может использовать document.documentElement.clientWidth, чтобы получить ширину устройства клиента и отслеживать ширину устройства, установив setInterval

как

setInterval(function(){
        width = document.documentElement.clientWidth;
        console.log(width);
    }, 1000);
Дж. Пат
источник
Просто используйте onresize. Например, document.getElementsByTagName ("BODY") [0] .onresize = function ()
RationalRabbit
0

Как и в случае с FYI, существует библиотека, называемая точками останова, которая определяет максимальную ширину, установленную в CSS, и позволяет использовать ее в условиях if-else JS с использованием знаков <=, <,>,> = и ==. Я нашел это весьма полезным. Размер полезной нагрузки менее 3 КБ.

Абхишек Дивекар
источник
0

На основе метода, который Bootstrap использует для установки своих точек останова Responsive , следующая функция возвращает xs, sm, md, lg или xl в зависимости от ширины экрана:

console.log(breakpoint());

function breakpoint() {
    let breakpoints = {
        '(min-width: 1200px)': 'xl',
        '(min-width: 992px) and (max-width: 1199.98px)': 'lg',
        '(min-width: 768px) and (max-width: 991.98px)': 'md',
        '(min-width: 576px) and (max-width: 767.98px)': 'sm',
        '(max-width: 575.98px)': 'xs',
    }

    for (let media in breakpoints) {
        if (window.matchMedia(media).matches) {
            return breakpoints[media];
        }
    }

    return null;
}

Омид Ариян
источник