Dapatkan lebar perangkat dalam javascript

128

Apakah ada cara untuk mendapatkan lebar perangkat pengguna, sebagai lawan dari lebar area pandang, menggunakan javascript?

Kueri media CSS menawarkan ini, seperti yang bisa saya katakan

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

dan

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

Ini berguna jika saya menargetkan ponsel cerdas dalam orientasi lanskap. Misalnya, di iOS, deklarasi max-width:640pxakan menargetkan mode lanskap dan potret, bahkan pada iPhone 4. Sejauh yang saya tahu, ini tidak terjadi pada Android, jadi menggunakan lebar perangkat dalam hal ini berhasil menargetkan kedua orientasi, tanpa menargetkan perangkat desktop.

Namun , jika saya menjalankan pengikatan javascript berdasarkan lebar perangkat, saya tampaknya dibatasi untuk menguji lebar area pandang, yang berarti tes tambahan seperti berikut ini,

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

Ini tidak tampak elegan bagi saya, mengingat petunjuk bahwa lebar perangkat tersedia untuk css.

Nicholas Evans
sumber
4
Coba situs web ini untuk mengetahui dimensi yang benar dari perangkat Anda. responsejs.com/labs/dimensions
Alpesh Darji
Modernizrdapat membantu Anda melakukan ini "dengan cara yang bersih & umum": stackoverflow.com/questions/25935686/… . Mengenai komentar pertama: Anda mungkin ingin google "Modernizr vs <otherLib> media query" untuk mencari tahu apa yang terbaik untuk kasus penggunaan Anda
Adrien Be

Jawaban:

215

Anda bisa mendapatkan lebar layar perangkat melalui properti screen.width.
Terkadang berguna juga untuk menggunakan window.innerWidth (biasanya tidak ditemukan di perangkat seluler) daripada lebar layar saat berurusan dengan browser desktop di mana ukuran jendela sering kali lebih kecil dari ukuran layar perangkat.

Biasanya, ketika berurusan dengan perangkat seluler DAN browser desktop saya menggunakan yang berikut ini:

 var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;
Bryan Rieger
sumber
5
Saya perhatikan ini tidak berfungsi seperti yang diharapkan pada browser asli Android 2.2. Jika saya tidak pada skala 1: 1, ini dapat melaporkan lebar yang jauh lebih lebar (selebar halaman) yang agak membuat frustrasi.
Chris Bosco
4
Ini mengembalikan 980 di Chrome Beta di Android dan 1024 di Browser Android pada HTC vivid.
Alex
4
@Alex Berikut adalah lebar viewport default browser. Jika Anda menggunakan meta-tag viewport dengan width=device-widthAnda harus mendapatkan nilai sebenarnya.
Brian Nickel
2
window.innerWidth mengembalikan 980 pada Iphone (Chrome / Safari). Bagaimana itu? <meta name = "viewport" content = "width = device-width" /> tidak membuat perbedaan.
Joao Leme
12
Bagaimana ini memiliki begitu banyak suara positif? var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;mengembalikan 667 di iphone 6 DAN 6 Plus. Solusi ini tidak bekerja dengan benar.
Ian S
60

Satu masalah dengan jawaban berguna Bryan Rieger adalah bahwa pada layar dengan kepadatan tinggi, perangkat Apple melaporkan screen.width dalam penurunan, sementara perangkat Android melaporkannya dalam piksel fisik. (Lihat http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html .) Saya sarankan menggunakan if (window.matchMedia('(max-device-width: 960px)').matches) {}pada browser yang mendukung matchMedia.


sumber
1
Ini sepertinya solusi yang jauh lebih baik dan sebenarnya menggunakan kueri media CSS. Saya ingin tahu apa dukungan browser untuk ini di seluruh platform seluler?
Carl Zulauf
1
Apakah ini penggunaan yang benar? if (window.matchMedia('(max-device-width: 960px)').matches) { var winW = (window.innerWidth > 0) ? window.innerWidth : screen.width; } else { var winW = screen.width; }
norsewulf
3
Saya tidak yakin apakah ini akan berhasil tanpa penskalaan yang disetel ke 1: 1 sebagai basis ...var isMobile = window.matchMedia && window.matchMedia('(max-device-width: 960px)').matches || screen.width <= 960;
Tracker1
3
Untuk Browser yang tidak mendukung, matchMedia()ada polyfill: github.com/paulirish/matchMedia.js
AvL
4
Menurut caniuse.com secara praktis semua browser, termasuk seluler, mendukung window.matchMedia ()
Mark Langer
14

Saya baru saja mendapat ide ini, jadi mungkin itu picik, tetapi tampaknya berfungsi dengan baik dan mungkin paling konsisten antara CSS dan JS Anda.

Di CSS Anda, Anda menetapkan nilai lebar-maksimal untuk html berdasarkan nilai layar @media:

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

    html { 
        max-width: 480px;
    }

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

}

Kemudian, dengan menggunakan JS (mungkin melalui kerangka kerja seperti JQuery), Anda hanya perlu memeriksa nilai lebar-maksimal dari tag html:

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

Sekarang Anda dapat menggunakan nilai ini untuk membuat perubahan bersyarat:

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

Jika menempatkan nilai lebar-maksimal pada tag html tampak menakutkan, maka mungkin Anda dapat menggunakan tag yang berbeda, yang hanya digunakan untuk tujuan ini. Untuk tujuan saya, tag html berfungsi dengan baik dan tidak memengaruhi markup saya.


Berguna jika Anda menggunakan Sass, dll : Untuk mengembalikan nilai yang lebih abstrak, seperti nama breakpoint, daripada nilai px Anda dapat melakukan sesuatu seperti:

  1. Buat elemen yang akan menyimpan nama breakpoint, misalnya <div id="breakpoint-indicator" />
  2. Menggunakan kueri media css mengubah properti konten untuk elemen ini, misalnya "besar" atau "seluler", dll. (Pendekatan kueri media dasar yang sama seperti di atas, tetapi menyetel properti 'konten' css alih-alih 'lebar-maks').
  3. Dapatkan nilai properti konten css menggunakan js atau jquery (mis. Jquery $('#breakpoint-indicator').css('content');), yang mengembalikan "besar", atau "seluler", dll. Bergantung pada properti konten apa yang disetel oleh kueri media.
  4. Bertindak berdasarkan nilai saat ini.

Sekarang Anda dapat bertindak pada nama breakpoint yang sama seperti yang Anda lakukan di sass, misalnya sass:, @include respond-to(xs)dan js if ($breakpoint = "xs) {}.

Yang paling saya sukai dari hal ini adalah saya dapat menentukan nama breakpoint saya semua di css dan di satu tempat (kemungkinan besar dokumen scss variabel) dan js saya dapat menindaklanjutinya secara independen.

RogerRoger
sumber
8

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

Ini harus menangani sebagian besar skenario.

ZNS
sumber
Math.max (window.innerWidth); akan memberi Anda lebar, termasuk scrollbar di FireFox, Edge, dan Chrome. document.documentElement.clientWidth; akan memberikan lebar di dalam scrollbar mana pun di browser tersebut. Di IE 11, keduanya akan menampilkan lebar termasuk scrollbar ..
RationalRabbit
6

Kamu harus menggunakan

document.documentElement.clientWidth

Ini dianggap sebagai kompatibilitas lintas browser, dan merupakan metode yang sama dengan jQuery (window) .width (); penggunaan.

Untuk informasi rinci, lihat: https://ryanve.com/lab/dimensions/

FooBar
sumber
5

Saya pikir menggunakan window.devicePixelRatiolebih elegan daripada window.matchMediasolusi:

if (window.innerWidth*window.devicePixelRatio <= 960 
    && window.innerHeight*window.devicePixelRatio <= 640) { 
    ... 
}
maxime schoeni
sumber
5

Anda dapat dengan mudah menggunakan

document.documentElement.clientWidth

Ulangi
sumber
3
Umumnya, jawaban jauh lebih membantu jika menyertakan penjelasan tentang tujuan kode, dan mengapa hal itu menyelesaikan masalah tanpa memperkenalkan orang lain.
Tim Diekmann
3

Ponsel Lumia memberikan screen.width yang salah (setidaknya pada emulator). Jadi mungkin Math.min(window.innerWidth || Infinity, screen.width)akan berfungsi di semua perangkat?

Atau sesuatu yang lebih gila:

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

Ya mybe, Anda dapat menggunakan document.documentElement.clientWidth untuk mendapatkan lebar perangkat klien dan terus melacak lebar perangkat dengan memakai setInterval

seperti

setInterval(function(){
        width = document.documentElement.clientWidth;
        console.log(width);
    }, 1000);
J. Pat
sumber
Cukup gunakan satu ukuran. Misalnya document.getElementsByTagName ("BODY") [0] .onresize = function ()
RationalRabbit
0

Sama seperti FYI, ada pustaka yang disebut breakpoints yang mendeteksi lebar-maksimal sebagaimana diatur dalam CSS dan memungkinkan Anda untuk menggunakannya dalam kondisi JS if-else menggunakan tanda <=, <,>,> = dan ==. Saya merasa cukup berguna. Ukuran muatan di bawah 3 KB.

Abhishek Divekar
sumber