Uzyskaj szerokość urządzenia w javascript

129

Czy istnieje sposób na uzyskanie szerokości urządzenia użytkownika, w przeciwieństwie do szerokości widocznego obszaru, za pomocą javascript?

Jak mogę powiedzieć, zapytania o media CSS oferują to

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

i

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

Jest to przydatne, jeśli kieruję reklamy na smartfony w orientacji poziomej. Na przykład w systemie iOS deklaracja max-width:640pxbędzie dotyczyła zarówno trybu poziomego, jak i pionowego, nawet na iPhonie 4. O ile wiem, nie dotyczy to Androida, więc użycie szerokości urządzenia w tym przypadku z powodzeniem jest ukierunkowane na obie orientacje, bez kierowania na komputery stacjonarne.

Jeśli jednak wywołuję powiązanie javascript na podstawie szerokości urządzenia, wydaje mi się, że ograniczam się do testowania szerokości widocznego obszaru, co oznacza dodatkowy test, jak poniżej,

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

Nie wydaje mi się to eleganckie, biorąc pod uwagę wskazówkę, że szerokość urządzenia jest dostępna dla css.

Nicholas Evans
źródło
4
Wypróbuj tę witrynę internetową, aby poznać prawidłowe wymiary swojego urządzenia. responsejs.com/labs/dimensions
Alpesh Darji
Modernizrmoże pomóc Ci to zrobić w „czysty i ogólny sposób”: stackoverflow.com/questions/25935686/… . Odnośnie pierwszego komentarza: możesz przejść do Google „Modernizr vs <otherLib> zapytanie o media”, aby dowiedzieć się, co działa najlepiej w Twoim przypadku
Adrien Be

Odpowiedzi:

214

Szerokość ekranu urządzenia można uzyskać za pomocą właściwości screen.width.
Czasami przydatne jest również użycie window.innerWidth (zwykle nie spotykane na urządzeniach mobilnych) zamiast szerokości ekranu w przypadku przeglądarek stacjonarnych, w których rozmiar okna jest często mniejszy niż rozmiar ekranu urządzenia.

Zwykle w przypadku urządzeń mobilnych ORAZ przeglądarek komputerowych używam:

 var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;
Bryan Rieger
źródło
5
Zauważyłem, że nie działa to zgodnie z oczekiwaniami w natywnej przeglądarce Androida 2.2. Jeśli nie jestem w skali 1: 1, może raportować znacznie szersze szerokości (tak szerokie, jak może być strona), co jest nieco frustrujące.
Chris Bosco,
4
Zwraca to 980 w Chrome Beta na Androida i 1024 w przeglądarce Android na HTC Vivid.
Alex
4
@Alex To są domyślne szerokości rzutni przeglądarek. Jeśli używasz z metatagiem viewport width=device-width, powinieneś otrzymać rzeczywistą wartość.
Brian Nickel
2
window.innerWidth zwraca 980 na Iphone (Chrome / Safari). W jaki sposób? <meta name = "viewport" content = "width = device-width" /> nie robi różnicy.
Joao Leme
13
Jak to ma tyle pozytywnych głosów? var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;zwraca 667 dla iPhone 6 ORAZ 6 Plus. To rozwiązanie nie działa poprawnie.
Ian S
60

Jednym z problemów z użyteczną odpowiedzią Bryana Riegera jest to, że na wyświetlaczach o dużej gęstości urządzenia Apple zgłaszają szerokość ekranu w spadkach, podczas gdy urządzenia z Androidem zgłaszają to w fizycznych pikselach. (Zobacz http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html .) Proponuję używać if (window.matchMedia('(max-device-width: 960px)').matches) {}w przeglądarkach obsługujących matchMedia.


źródło
1
Wydaje się, że jest to znacznie lepsze rozwiązanie i faktycznie wykorzystuje zapytania o media CSS. Zastanawiam się, jaka jest obsługa przeglądarki na różnych platformach mobilnych?
Carl Zulauf
1
Czy to byłoby właściwe użycie? if (window.matchMedia('(max-device-width: 960px)').matches) { var winW = (window.innerWidth > 0) ? window.innerWidth : screen.width; } else { var winW = screen.width; }
norsewulf
3
Nie jestem pewien, czy to zadziała bez skalowania ustawionego na 1: 1 jako podstawa ...var isMobile = window.matchMedia && window.matchMedia('(max-device-width: 960px)').matches || screen.width <= 960;
Tracker1
3
W przypadku przeglądarek, które nie obsługują, matchMedia()istnieje polifill: github.com/paulirish/matchMedia.js
AvL
4
Według caniuse.com praktycznie wszystkie przeglądarki, w tym mobilne, obsługują window.matchMedia ()
Mark Langer
14

Właśnie wpadłem na ten pomysł, więc może jest krótkowzroczny, ale wydaje się, że działa dobrze i może być najbardziej spójny między twoim CSS i JS.

W swoim CSS ustawiasz wartość max-width dla html na podstawie wartości @media screen:

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

    html { 
        max-width: 480px;
    }

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

}

Następnie, używając JS (prawdopodobnie za pośrednictwem frameworka takiego jak JQuery), po prostu sprawdzisz wartość max-width tagu html:

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

Teraz możesz użyć tej wartości, aby wprowadzić zmiany warunkowe:

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

Jeśli umieszczenie wartości max-width w tagu html wydaje się przerażające, być może możesz umieścić inny tag, taki, który jest używany tylko do tego celu. Dla mojego celu tag html działa dobrze i nie wpływa na moje znaczniki.


Przydatne, jeśli używasz Sass itp . : Aby zwrócić bardziej abstrakcyjną wartość, taką jak nazwa punktu przerwania, zamiast wartości px możesz zrobić coś takiego:

  1. Utwórz element, który będzie przechowywać nazwę punktu przerwania, np <div id="breakpoint-indicator" />
  2. Użycie zapytań o media css zmienia właściwość content dla tego elementu, np. „Large” lub „mobile” itp. (To samo podstawowe podejście do zapytań o media jak powyżej, ale ustawienie właściwości css „content” zamiast „max-width”).
  3. Uzyskaj wartość właściwości treści css za pomocą js lub jquery (np. Jquery $('#breakpoint-indicator').css('content');), która zwraca wartość „large”, „mobile” itp. W zależności od tego, na jaką właściwość content ustawiono zapytanie o media.
  4. Działaj na podstawie aktualnej wartości.

Teraz możesz działać na tych samych nazwach punktów przerwania, co w sass, np. Sass: @include respond-to(xs)i js if ($breakpoint = "xs) {}.

Szczególnie podoba mi się w tym to, że mogę zdefiniować wszystkie nazwy moich punktów przerwania w css iw jednym miejscu (prawdopodobnie dokument ze zmiennymi scss), a mój js może działać na nich niezależnie.

Przyjąłem
źródło
8

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

Powinno to obsłużyć większość scenariuszy.

ZNS
źródło
Math.max (window.innerWidth); poda szerokość, w tym paski przewijania w FireFox, Edge i Chrome. document.documentElement.clientWidth; poda szerokość wewnątrz pasków przewijania w tych przeglądarkach. W IE 11 obie pokażą szerokość, w tym paski przewijania ..
RationalRabbit
7

Powinieneś użyć

document.documentElement.clientWidth

Jest to traktowane jako kompatybilność z różnymi przeglądarkami i jest tą samą metodą co jQuery (okno) .width (); używa.

Po szczegółowe informacje zajrzyj na: https://ryanve.com/lab/dimensions/

FooBar
źródło
5

Myślę, że używanie window.devicePixelRatiojest bardziej eleganckie niż window.matchMediarozwiązanie:

if (window.innerWidth*window.devicePixelRatio <= 960 
    && window.innerHeight*window.devicePixelRatio <= 640) { 
    ... 
}
maxime schoeni
źródło
5

możesz łatwo użyć

document.documentElement.clientWidth

Reundo
źródło
3
Ogólnie odpowiedzi są znacznie bardziej pomocne, jeśli zawierają wyjaśnienie, do czego służy kod i dlaczego to rozwiązuje problem bez wprowadzania innych.
Tim Diekmann
3

Telefony Lumia podają nieprawidłową szerokość ekranu (przynajmniej na emulatorze). Więc możeMath.min(window.innerWidth || Infinity, screen.width) będzie działać na wszystkich urządzeniach?

Albo coś bardziej szalonego:

for (var i = 100; !window.matchMedia('(max-device-width: ' + i + 'px)').matches; i++) {}
var deviceWidth = i;
Munawwar
źródło
2

Możesz użyć document.documentElement.clientWidth, aby uzyskać szerokość urządzenia klienta i śledzić szerokość urządzenia, ustawiając setInterval

tak jak

setInterval(function(){
        width = document.documentElement.clientWidth;
        console.log(width);
    }, 1000);
J. Pat
źródło
Po prostu użyj onresize. Na przykład document.getElementsByTagName ("BODY") [0] .onresize = function ()
RationalRabbit
0

Podobnie jak FYI, istnieje biblioteka o nazwie breakpoints, która wykrywa maksymalną szerokość ustawioną w CSS i pozwala na użycie jej w warunkach JS if-else przy użyciu znaków <=, <,>,> = i ==. Uważam, że to całkiem przydatne. Rozmiar ładunku nie przekracza 3 KB.

Abhishek Divekar
źródło