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

Есть ли способ получить ширину устройства пользователя, а не ширину области просмотра, с помощью 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.


person Nicholas Evans    schedule 27.07.2011    source источник
comment
Посетите этот веб-сайт, чтобы узнать правильные размеры вашего устройства. responsejs.com/labs/dimensions   -  person Alpesh Darji    schedule 17.07.2012
comment
Modernizr может помочь вам сделать это простым и универсальным способом: stackoverflow.com/questions/25935686/. Что касается 1-го комментария: вы можете захотеть использовать медиа-запрос Google Modernizr vs ‹otherLib›, чтобы узнать, что лучше всего подходит для вашего варианта использования.   -  person Adrien Be    schedule 08.12.2016


Ответы (12)


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

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

 var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;
person Bryan Rieger    schedule 27.07.2011
comment
Я заметил, что это не работает должным образом в собственном браузере Android 2.2. Если я не использую масштаб 1: 1, он может отображать гораздо более широкую ширину (настолько широкую, насколько может быть страница), что немного расстраивает. - person Chris Bosco; 21.09.2011
comment
Это возвращает 980 в бета-версии Chrome на Android и 1024 в браузере Android на HTC vivid. - person Alex; 24.05.2012
comment
@Alex Это ширина области просмотра по умолчанию для браузеров. Если вы используете метатег области просмотра с width=device-width, вы должны получить фактическое значение. - person Brian Nickel♦; 24.08.2012
comment
window.innerWidth возвращает 980 на Iphone (Chrome / Safari). Как так? ‹Meta name = viewport content = width = device-width /› не имело никакого значения. - person Joao Leme; 02.10.2012
comment
На Retina iPhone ширина устройства (применяется с помощью метатега) соответствует screen.width (320 пикселей), но на устройстве Android с двойным соотношением пикселей ширина устройства составляет половину от screen.width (например, 360 пикселей / 720 пикселей). Я ищу способ определить масштабируемую ширину устройства (т.е. 320 пикселей на устройстве с двойным соотношением пикселей шириной 640 пикселей), который работает как на iOS, так и на Android. Ответ Брейдена ниже, похоже, решает эту проблему. - person Alasdair McLeay; 03.12.2013
comment
Как у этого столько голосов? var width = (window.innerWidth > 0) ? window.innerWidth : screen.width; возвращает 667 на iphone 6 И 6 Plus. Это решение работает некорректно. - person Ian S; 19.11.2015
comment
Так не пойдет. Скажем, например, у вас есть рабочий стол с разрешением 1920x1080, но размер вашего окна изменен до 600x400. Это вернет 600. - person ZNS; 19.02.2018
comment
@lan S не имеет смысла, однако я разместил здесь более надежное решение stackoverflow.com/a/58713246/2118665 - person FooBar; 05.11.2019

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

person Community    schedule 07.12.2012
comment
Это кажется гораздо лучшим решением и на самом деле использует медиа-запросы CSS. Интересно, что это за поддержка браузером на мобильных платформах? - person Carl Zulauf; 30.01.2013
comment
@CarlZulauf, я тестировал полдюжины устройств с отличными результатами. Если window.matchMedia, используйте указанное выше, иначе проверьте screen.width. - person ; 30.01.2013
comment
Будет ли это правильным использованием? if (window.matchMedia('(max-device-width: 960px)').matches) { var winW = (window.innerWidth > 0) ? window.innerWidth : screen.width; } else { var winW = screen.width; } - person norsewulf; 09.02.2013
comment
К сожалению, norsewulf, matchMedia может выдавать только логические значения. var isMobile; if (window.matchMedia) {isMobile = window.matchMedia('(max-device-width: 960px)').matches;} else {isMobile = screen.width <= 960;} - person ; 12.02.2013
comment
Я не уверен, что это будет работать без масштабирования, установленного на 1: 1 в качестве основы ... var isMobile = window.matchMedia && window.matchMedia('(max-device-width: 960px)').matches || screen.width <= 960; - person Tracker1; 28.02.2013
comment
Для браузеров, не поддерживающих matchMedia(), существует полифилл: github.com/paulirish/matchMedia.js - person AvL; 01.01.2014
comment
Согласно caniuse.com практически все браузеры, включая мобильные, поддерживают window.matchMedia () - person Mark Langer; 16.01.2018
comment
Похоже, что в 2018 году поддержка браузеров улучшилась по всем направлениям. - person Jack Stone; 28.03.2018

У меня только что возникла эта идея, так что, возможно, она близорука, но, похоже, она работает хорошо и может быть наиболее последовательной между вашим 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 и т. д.: чтобы вернуть более абстрактное значение, такое как имя точки останова, вместо значения в пикселях вы можете сделать что-то вроде:

  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 могут действовать на них независимо.

person RogerRoger    schedule 18.02.2013

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

document.documentElement.clientWidth

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

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

person FooBar    schedule 05.11.2019

Проверь это

const mq = window.matchMedia( "(min-width: 500px)" );

if (mq.matches) {
  // window width is at least 500px
} else {
  // window width is less than 500px
}

https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia

person MEAbid    schedule 29.01.2018

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

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

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

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

if (window.innerWidth*window.devicePixelRatio <= 960 
    && window.innerHeight*window.devicePixelRatio <= 640) { 
    ... 
}
person maxime schoeni    schedule 07.05.2017

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

document.documentElement.clientWidth

person Reundo    schedule 22.05.2018
comment
Как правило, ответы намного полезнее, если они включают объяснение того, для чего предназначен код, и почему это решает проблему, не вводя других. - person Tim Diekmann; 23.05.2018

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

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

for (var i = 100; !window.matchMedia('(max-device-width: ' + i + 'px)').matches; i++) {}
var deviceWidth = i;
person Munawwar    schedule 13.07.2015

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

как

setInterval(function(){
        width = document.documentElement.clientWidth;
        console.log(width);
    }, 1000);
person J. Pat    schedule 16.10.2019
comment
Просто используйте onresize. Например, document.getElementsByTagName (BODY) [0] .onresize = function () - person RationalRabbit; 17.03.2020

Основываясь на методе, который Bootstrap использует для установки своих Адаптивных точек останова, следующая функция возвращает 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;
}

person Omid Ariyan    schedule 15.08.2020

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

person Abhishek Divekar    schedule 06.01.2020