Come ottenere le dimensioni della finestra del browser?


789

Voglio offrire ai miei visitatori la possibilità di vedere immagini in alta qualità, esiste un modo per rilevare le dimensioni della finestra?

O meglio, la dimensione del viewport del browser con JavaScript? Vedi l'area verde qui:


10
Quello che faccio è impostare un elemento di solito html all'altezza del 100% e ottenere la sua altezza. Lavori semplici ovunque.
Muhammad Umer,

1
@MuhammadUmer buona cattura! Se sei frustrato nell'ottenere le dimensioni (e lo farai, sui telefoni cellulari senza jQuery), puoi utilizzare getComputedStyleil htmltag espanso .
Dan

Inoltre, è possibile utilizzare la libreria W , che gestisce il rilevamento delle finestre tra browser;)
pyrsmk,

Risposte:


1328

Cross-browser @media (width) e @media (height)valori 

const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);

window.innerWidth e .innerHeight

  • ottiene il viewport CSS @media (width) e @media (height)che includono barre di scorrimento
  • initial-scalee le variazioni di zoom possono causare un ridimensionamento errato dei valori mobili a ciò che PPK chiama il visual viewport ed essere più piccolo dei @mediavalori
  • lo zoom potrebbe causare uno scarto di 1px a causa dell'arrotondamento nativo
  • undefined in IE8-

document.documentElement.clientWidth e .clientHeight

risorse


4
@ 01100001 Sostituire $con verge. Se vuoi integrarti in jQuery, fallo jQuery.extend(verge). Vedi: verge.airve.com/#static
ryanve

4
Volevo solo menzionare che in IE8 (e forse in altri) devi avere la <!DOCTYPE html>parte superiore della pagina affinché il codice funzioni.
Tzury Bar Yochay,

6
Non sono contento di clientWidth / Height su dispositivi mobili, davvero tripleodeon.com/wp-content/uploads/2011/12/table.html
Dan

24
A meno che non mi manchi qualcosa, questa risposta è sbagliata. In Chrome, almeno, document.documentElement.clientHeightrestituisce l' altezza della pagina , mentre window.innerHeightrestituisce l' altezza della finestra . Grande differenza.
Nate,

2
diverse variabili di dimensione dello schermo / soluzioni test live: ryanve.com/lab/dimensions
Alex Pandrea

106

Funzioni di dimensione jQuery

$(window).width() e $(window).height()


60
@allyourcode, impossibile, jQuery è la risposta a tutti .
Xeoncross,

21
Questo non ottiene la dimensione del viewport, ma la dimensione complessiva del documento. Provalo.
Alejandro García Iglesias,

2
Per i browser che visualizzano le barre degli strumenti del componente aggiuntivo come HTML con postitionning fisso, questa soluzione non funziona, soprattutto se si desidera utilizzare nel posizionamento e nelle percentuali migliori del codice.
Adib Aroui,

7
@AlejandroIglesias: No, l'ho appena provato su questa pagina SO. $(window).height();restituisce 536, mentre $("html").height();restituisce 10599
Flimm

2
Avvertendo queste dimensioni non includono le barre di scorrimento (che hanno dimensioni diverse in browser e piattaforme diversi) e pertanto non combaciano con le query multimediali CSS, altre risposte qui risolvono tuttavia questo problema.
Spencer O'Reilly,

75

È possibile utilizzare le proprietà window.innerWidth e window.innerHeight .

innerHeight vs outerHeight


29
Anche se questo non funziona in IE +1 per il diagramma: D. Per una domanda come questa, dovrebbe essere un crimine non averne di più.
codice alleato

8
@CMS document.documentElement.clientWidthè più preciso e ampiamente supportato rispetto awindow.innerWidth
ryanve il

6
@ryanve Se per "più preciso" intendi "non fa nemmeno la stessa cosa da remoto", allora sì: P
scatola

Firefox Beta? È qualcosa che apparteneva al museo.
Derek 朕 會 功夫

@boxed In Mobile Safari, document.documentElement.clientWidthmi dà la larghezza della finestra mentre window.innerWidth mi dà la larghezza del documento. Sì, in questo modo.
Giovanni

33

Se non stai usando jQuery, diventa brutto. Ecco uno snippet che dovrebbe funzionare su tutti i nuovi browser. Il comportamento è diverso in modalità Quirks e modalità standard in IE. Questo se ne occupa.

var elem = (document.compatMode === "CSS1Compat") ? 
    document.documentElement :
    document.body;

var height = elem.clientHeight;
var width = elem.clientWidth;

8
Questo non ti dà l'altezza della pagina, non il viewport? Questo è ciò che questa pagina sembra indicare: developer.mozilla.org/en/DOM/element.clientHeight
allyourcode

4
Stai utilizzando clientHeightl' document.documentElementelemento, che ti darà la dimensione della finestra. Per ottenere le dimensioni del documento, dovresti farlo document.body.clientHeight. Come spiega Chetan, questo comportamento si applica ai browser moderni. È facile da testare. Basta aprire una console e digitare document.documentElement.clientHeightsu diverse schede aperte.
Gajus

13

So che ha una risposta accettabile, ma mi sono imbattuto in una situazione in cui clientWidthnon ha funzionato, dato che iPhone (almeno il mio) ha restituito 980, non 320, quindi l'ho usato window.screen.width. Stavo lavorando su un sito esistente, essendo stato "responsive" e avevo bisogno di forzare browser più grandi a utilizzare un meta-viewport diverso.

Spero che questo aiuti qualcuno, potrebbe non essere perfetto, ma funziona nei miei test su iOS e 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

Ho cercato e trovato una modalità cross browser:

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>


si noti che l'utilizzo di uno stack ifflow di un iframe che circonda lo snippet di codice incasina il risultato
Miller,

11

Sono riuscito a trovare una risposta definitiva in JavaScript: The Definitive Guide, 6th Edition di O'Reilly, p. 391:

Questa soluzione funziona anche in modalità Quirks, mentre l'attuale soluzione di ryanve e ScottEvernden no.

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 };

}

tranne per il fatto che mi chiedo perché la linea if (document.compatMode == "CSS1Compat")non lo sia if (d.compatMode == "CSS1Compat"), tutto sembra a posto.


stai parlando del display Retina o Landscape vs Portrait o del tag meta viewport? Non intendi i pixel virtuali come in snowdragonledhk.com/… ?
polarità

1) Quando parlo di display ad alto DPI intendo pixel virtuali spiegati qui: stackoverflow.com/a/14325619/139361 . Ogni schermo di iPhone ha esattamente 320 pixel di larghezza. 2) Dico che: a) documentElement.clientWidthnon risponde al cambio di orientamento del dispositivo su iOS. b) visualizza il conteggio dei pixel fisici (praticamente inutili) invece dei pixel virtuali
Dan,

11

Se stai cercando una soluzione non jQuery che fornisca valori corretti in pixel virtuali su dispositivi mobili e pensi che sia semplice window.innerHeighto in document.documentElement.clientHeightgrado di risolvere il tuo problema, ti preghiamo di studiare prima questo link: https://tripleodeon.com/assets/2011/12/ table.html

Lo sviluppatore ha effettuato buoni test che rivelano il problema: è possibile ottenere valori imprevisti per display Android / iOS, orizzontale / verticale, normale / alta densità.

La mia risposta attuale non è ancora Silver Bullet (// todo), ma piuttosto un avvertimento per coloro che stanno per copiare e incollare rapidamente qualsiasi soluzione data da questo thread nel codice di produzione.

Stavo cercando la larghezza della pagina in pixel virtuali su dispositivo mobile e ho scoperto che l'unico codice funzionante è (inaspettatamente!) window.outerWidth. Esaminerò più avanti questa tabella per la soluzione corretta che fornisce l'altezza esclusa la barra di navigazione, quando ho tempo.



9

C'è una differenza tra window.innerHeighte document.documentElement.clientHeight. Il primo include l'altezza della barra di scorrimento orizzontale.


1
Hai provato la tua risposta su tutti i sistemi operativi, sui display Retina e in modalità orizzontale / verticale? Questo link copre sistemi piuttosto obsoleti, ma dimostra che il tuo codice non funziona: tripleodeon.com/wp-content/uploads/2011/12/table.html
Dan

6

Una soluzione conforme agli standard W3C sarebbe quella di creare un div trasparente (ad esempio dinamicamente con JavaScript), impostarne la larghezza e l'altezza su 100vw / 100vh (unità Viewport) e quindi ottenere offsetWidth e offsetHeight. Successivamente, l'elemento può essere rimosso di nuovo. Questo non funzionerà nei browser più vecchi perché le unità viewport sono relativamente nuove, ma se invece non ti interessano di loro, ma piuttosto degli standard (che saranno presto), potresti sicuramente procedere in questo modo:

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);

Ovviamente, puoi anche impostare objNode.style.position = "fixed" e quindi usare il 100% come larghezza / altezza - questo dovrebbe avere lo stesso effetto e migliorare la compatibilità in una certa misura. Inoltre, impostare la posizione su fixed potrebbe essere una buona idea in generale, perché altrimenti il ​​div sarà invisibile ma consumerà un po 'di spazio, il che porterà alla comparsa di barre di scorrimento, ecc.


Sfortunatamente, la realtà distrugge completamente la tua "soluzione standard W3C": 1) caniuse.com/viewport-units , 2) caniuse.com/#feat=css-fixed . Ciò di cui gli sviluppatori hanno bisogno è la soluzione che funziona, non "dovrebbe teoricamente funzionare".
Dan,

Se possiamo fare affidamento sugli standard, non abbiamo nemmeno bisogno di tutte quelle soluzioni cross-browser. Una soluzione che risponde alle specifiche non è una soluzione.
Derek 朕 會 功夫

3

Questo è il modo in cui lo faccio, l'ho provato in IE 8 -> 10, FF 35, Chrome 40, funzionerà molto bene in tutti i browser moderni (come viene definito window.innerWidth) e in IE 8 (senza finestra. innerWidth) funziona perfettamente, qualsiasi problema (come il flashing a causa di overflow: "nascosto"), per favore segnalalo. Non sono molto interessato all'altezza del viewport poiché ho creato questa funzione solo per aggirare alcuni strumenti reattivi, ma potrebbe essere implementato. Spero che sia d'aiuto, apprezzo commenti e suggerimenti.

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)
  );
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.