Come rilevare il livello di zoom della pagina in tutti i browser moderni?


310
  1. Come posso rilevare il livello di zoom della pagina in tutti i browser moderni? Mentre questo thread spiega come farlo in IE7 e IE8, non riesco a trovare una buona soluzione cross-browser.

  2. Firefox memorizza il livello di zoom della pagina per un accesso futuro. Al caricamento della prima pagina, sarei in grado di ottenere il livello di zoom? Da qualche parte ho letto che funziona quando si verifica una modifica dello zoom dopo il caricamento della pagina.

  3. C'è un modo per intrappolare l' 'zoom'evento?

Ne ho bisogno perché alcuni dei miei calcoli sono basati su pixel e possono fluttuare quando ingranditi.


Campione modificato fornito da @tfl

Questa pagina avvisa diversi valori di altezza quando ingranditi. [jsFiddle]

<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js" type="text/javascript"/></script>
    </head>
    <body>
        <div id="xy" style="border:1px solid #f00; width:100px;">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sollicitudin tortor in lacus tincidunt volutpat. Integer dignissim imperdiet mollis. Suspendisse quis tortor velit, placerat tempor neque. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent bibendum auctor lorem vitae tempor. Nullam condimentum aliquam elementum. Nullam egestas gravida elementum. Maecenas mattis molestie nisl sit amet vehicula. Donec semper tristique blandit. Vestibulum adipiscing placerat mollis.</div>
        <button onclick="alert($('#xy').height());">Show</button>
    </body>
</html>

1
Fondamentalmente voglio conoscere la dimensione di un DIV con uno zoom del 100%.
Comprende l'

4
Fondamentalmente non c'è modo di rilevare lo zoom nel 2019 : ho testato tutte le soluzioni seguenti su Chrome 78 su Mac Catalina e nessuna di queste ha funzionato.
Collimarco,

Risposte:


274

Ora è un casino ancora più grande di quanto non fosse quando questa domanda è stata posta per la prima volta. Dalla lettura di tutte le risposte e i post sul blog che ho trovato, ecco un riepilogo. Ho anche impostato questa pagina per testare tutti questi metodi di misurazione del livello di zoom .

Modifica (12-12-2011): ho aggiunto un progetto che può essere clonato: https://github.com/tombigel/detect-zoom

  • IE8 : screen.deviceXDPI / screen.logicalXDPI(o, per il livello di zoom relativo allo zoom predefinito, screen.systemXDPI / screen.logicalXDPI)
  • IE7 : var body = document.body,r = body.getBoundingClientRect(); return (r.left-r.right)/body.offsetWidth;(grazie a questo esempio o a questa risposta )
  • SOLO FF3.5 : screen.width/ larghezza dello schermo di query media (vedi sotto) (sfrutta il fatto che screen.widthutilizza i pixel del dispositivo ma la larghezza MQ utilizza i pixel CSS - grazie alle larghezze Quirksmode )
  • FF3.6 : nessun metodo noto
  • FF4 + : media query di ricerca binaria (vedi sotto)
  • WebKit : https://www.chromestatus.com/feature/5737866978131968 (grazie a Teo nei commenti)
  • WebKit : misura la dimensione preferita di un div con -webkit-text-size-adjust:none.
  • WebKit : (rotto da r72591 ) document.width / jQuery(document).width()(grazie a Dirk van Oosterbosch sopra ). Per ottenere il rapporto in termini di pixel del dispositivo (anziché rispetto allo zoom predefinito), moltiplicare per window.devicePixelRatio.
  • Vecchio WebKit? (non verificato):parseInt(getComputedStyle(document.documentElement,null).width) / document.documentElement.clientWidth (da questa risposta )
  • Opera : document.documentElement.offsetWidth/ larghezza di un position:fixed; width:100%div. da qui ( la tabella delle larghezze di Quirksmode dice che è un bug; innerWidth dovrebbe essere CSS px). Usiamo la posizione: elemento fisso per ottenere la larghezza della finestra compreso lo spazio in cui si trovano le barre di scorrimento ; document.documentElement.clientWidth esclude questa larghezza. Questo è rotto da qualche tempo nel 2011; Non so più come ottenere il livello di zoom in Opera.
  • Altro : soluzione Flash di Sebastian
  • Inaffidabile: ascolta gli eventi del mouse e misura i cambiamenti in screenX / cambi in clientX

Ecco una ricerca binaria per Firefox 4, poiché non conosco alcuna variabile in cui è esposta:

<style id=binarysearch></style>
<div id=dummyElement>Dummy element to test media queries.</div>
<script>
var mediaQueryMatches = function(property, r) {
  var style = document.getElementById('binarysearch');
  var dummyElement = document.getElementById('dummyElement');
  style.sheet.insertRule('@media (' + property + ':' + r +
                         ') {#dummyElement ' +
                         '{text-decoration: underline} }', 0);
  var matched = getComputedStyle(dummyElement, null).textDecoration
      == 'underline';
  style.sheet.deleteRule(0);
  return matched;
};
var mediaQueryBinarySearch = function(
    property, unit, a, b, maxIter, epsilon) {
  var mid = (a + b)/2;
  if (maxIter == 0 || b - a < epsilon) return mid;
  if (mediaQueryMatches(property, mid + unit)) {
    return mediaQueryBinarySearch(
        property, unit, mid, b, maxIter-1, epsilon);
  } else {
    return mediaQueryBinarySearch(
        property, unit, a, mid, maxIter-1, epsilon);
  }
};
var mozDevicePixelRatio = mediaQueryBinarySearch(
    'min--moz-device-pixel-ratio', '', a, b, maxIter, epsilon);
var ff35DevicePixelRatio = screen.width / mediaQueryBinarySearch(
    'min-device-width', 'px', 0, 6000, 25, .0001);
</script>

1
Ottimo lavoro, anche se questo non funziona per me in Internet Explorer 8.0.7601.17514 (ultimo). Qualche possibilità di concludere tutto in un'unica funzione getZoom () che funziona su tutti i browser? Forse rilasciare anche come plugin jQuery? Bel lavoro di nuovo.
ripper234

1
@yonran great plugin !, Ma non funziona in IE9 dovrebbe essere zoom: screen.deviceXDPI / screen.logicalXDPI,invece dizoom: screen.systemXDPI / screen.logicalXDPI,
Daniel

1
@RobW, quando l'ho scritto per la prima volta per Firefox 4, Firefox non ce l'aveva matchMedia. Paul Irish ha anche scritto un simile polyfill MatchMedia che fa parte di Modernizr .
yonran,

7
Buone notizie a tutti! Alla fine ce l'hanno fatta! API Vieport! chromestatus.com/feature/5737866978131968 Lo provo , grandi cose!
Teo

3
L'API Viewport funziona solo con zoom con pinch; se ingrandisci il desktop, la scala è 1. @Jason T Featheringham ci sono ragioni diverse dalla "discriminazione" per voler conoscere il livello di zoom. Lo zoom è impostato su tutte le pagine di un dominio, ma potresti volerlo gestire diversamente in una pagina di gioco o in un popup di estensione rispetto a una pagina di aiuto.
Pudica,

61

Puoi provare

var browserZoomLevel = Math.round(window.devicePixelRatio * 100);

Questo ti darà il livello percentuale di zoom del browser su display non retina. Per i display DPI / retina elevati, si otterrebbero valori diversi (ad es. 200 per Chrome e Safari, 140 per Firefox).

Per catturare l'evento zoom puoi usare

$(window).resize(function() { 
// your code 
});

1
Funziona perfettamente, anche su dispositivi mobili. È anche abbastanza interessante vedere quali dispositivi mobili hanno cosa devicePixelRatio. Questo mi ha anche aiutato moltissimo a cambiare un fixedelemento in un elemento absoluteposizionato quando si verifica l'evento zoom o quando devicePixelRatiocambia il valore iniziale . Perfetto! Grazie!!
lowtechsun,

12
Non funziona come previsto: restituisce 200 in Chrome su MacBook con retina quando il browser non è ingrandito.
Terite,

19
I browser con supporto per schermi DPI alti non daranno il risultato atteso quando si utilizza tale display, né Safari indipendentemente dal display.
Fredrik C,

Solo per chiunque si preoccupi, su IE funziona solo su IE11 (restituirà NaN su IE10 o inferiore)
scunliffe

3
Math.round(window.devicePixelRatio * 100)funziona su Chrome, IE, Edge e Firefox. Safari su iMac restituisce sempre 200.
Super Jade

45

Per me, per Chrome / Webkit, document.width / jQuery(document).width()non ha funzionato. Quando ho reso la mia finestra piccola e ingrandita il mio sito in modo tale che apparissero barre di scorrimento orizzontali, document.width / jQuery(document).width()non era uguale a 1 con lo zoom predefinito. Questo perché document.widthinclude parte del documento all'esterno della finestra.

Usando window.innerWidthe ha window.outerWidthfunzionato. Per qualche motivo in Chrome, outerWidth viene misurato in pixel dello schermo e innerWidth viene misurato in pixel css.

var screenCssPixelRatio = (window.outerWidth - 8) / window.innerWidth;
if (screenCssPixelRatio >= .46 && screenCssPixelRatio <= .54) {
  zoomLevel = "-4";
} else if (screenCssPixelRatio <= .64) {
  zoomLevel = "-3";
} else if (screenCssPixelRatio <= .76) {
  zoomLevel = "-2";
} else if (screenCssPixelRatio <= .92) {
  zoomLevel = "-1";
} else if (screenCssPixelRatio <= 1.10) {
  zoomLevel = "0";
} else if (screenCssPixelRatio <= 1.32) {
  zoomLevel = "1";
} else if (screenCssPixelRatio <= 1.58) {
  zoomLevel = "2";
} else if (screenCssPixelRatio <= 1.90) {
  zoomLevel = "3";
} else if (screenCssPixelRatio <= 2.28) {
  zoomLevel = "4";
} else if (screenCssPixelRatio <= 2.70) {
  zoomLevel = "5";
} else {
  zoomLevel = "unknown";
}

1
Molto bella. E se hai solo bisogno di sapere se è ingrandito o meno in Chrome:isZoomed = (screenCssPixelRatio < .98 || screenCssPixelRatio > 1.02)
Brent Faust

1
Bene, window.outerWidth è cambiato anche con lo zoom. Inoltre, non su tutti i sistemi operativi la larghezza del bordo della finestra è di 8 pixel (anche sullo stesso sistema operativo il design può variare). Comunque suggerirei di sottrarre 16, non 8, poiché hai i bordi della finestra due volte. Inoltre, alcuni browser hanno un bordo sulla loro finestra di rendering reale (come FF) e altri no (Safari) - ma anche questo dipende da quale sistema operativo usi il browser (ad esempio Safari ha un bordo su Windows). Eseguire il backup della larghezza interna interna (ad esempio al caricamento della pagina) e utilizzarlo per confrontare funziona meglio, ma solo se lo zoom inizionale era al 100% ...
StanE

1
Output 0 non importa cosa per me (2017, feb).
Tiberiu-Ionuț Stan,

1
switchL'istruzione può essere migliore di molte altre istruzioni if.
Edric

Non funziona: appena testato su Chrome su Mac e restituisce sempre lo stesso rapporto, indipendentemente dal livello di zoom
collimarco,

16

Io e il mio collega abbiamo usato la sceneggiatura da https://github.com/tombigel/detect-zoom . Inoltre, abbiamo anche creato dinamicamente un elemento svg e verificato la sua proprietà currentScale. Funziona benissimo su Chrome e probabilmente anche sulla maggior parte dei browser. Su FF la funzione "solo testo zoom" deve essere disattivata. SVG è supportato sulla maggior parte dei browser. Al momento della stesura di questo documento, testato su IE10, FF19 e ​​Chrome28.

var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
svg.setAttribute('version', '1.1');
document.body.appendChild(svg);
var z = svg.currentScale;
... more code ...
document.body.removeChild(svg);

Questo metodo ora riporta sempre svg.currentScale = 1 in Firefox 29. Probabilmente perché ridimensionano le figure dell'intero schermo in base allo zoom che è un bug . IE11 sembra avere lo stesso problema sul desktop con l'altezza dello schermo adattata al dispositivo viewportPixelRatio che è abbastanza rovinato.
hexalys,

11

Ho trovato questo articolo estremamente utile. Grazie enormi a yonran. Volevo trasmettere alcuni apprendimenti aggiuntivi che ho trovato durante l'implementazione di alcune delle tecniche che ha fornito. In FF6 e Chrome 9, è stato aggiunto il supporto per le query multimediali da JS, che può semplificare notevolmente l'approccio di media query necessario per determinare lo zoom in FF. Consulta i documenti su MDN qui . Per i miei scopi, avevo solo bisogno di rilevare se il browser era ingrandito o ridotto, non avevo bisogno del fattore di zoom effettivo. Sono stato in grado di ottenere la mia risposta con una riga di JavaScript:

var isZoomed = window.matchMedia('(max--moz-device-pixel-ratio:0.99), (min--moz-device-pixel-ratio:1.01)').matches;

Combinando questo con le soluzioni IE8 + e Webkit, che erano anche linee singole, sono stato in grado di rilevare lo zoom sulla maggior parte dei browser colpendo la nostra app con solo poche righe di codice.


4
Potresti fornire un codice su come rilevare lo zoom effettivo utilizzando la query multimediale?
TN.

Prova a usare solo "(larghezza: <X> px) e (altezza: <Y> px)" dove <X> e <Y> sono rispettivamente window.innerWidth e window.innerHeight. Funziona anche con quantità minime di zoom. Funziona anche in Safari.
max

@max Puoi fornire un codice JSFIddle o un esempio di come questo sembra messo insieme, per favore?
lowtechsun,

Riporta sempre true su dispositivi retina come macbook pro.
Matthew Sanders,

codepen.io/anon/pen/LgrGjJ mostra una ricerca binaria con query multimediali, ma è uguale alla query devicePixelRatio: tiene conto del ridimensionamento della visualizzazione.
ZachB,

11
zoom = ( window.outerWidth - 10 ) / window.innerWidth

Questo è tutto ciò di cui hai bisogno.


Perché sottrarre 10da outerWidth?
callum,

Probabilmente per la barra di scorrimento. Anche ogni barra di scorrimento è diversa, come in iOS è molto più piccola. Inoltre, questa soluzione sembra essere solo cromata
Sarah,

1
Non funziona se l'utente ha una barra laterale come i segnalibri in FF
Gerrit Sedlaczek

7

Ho una soluzione per questo a partire da gennaio 2016. Testato funzionante con browser Chrome, Firefox e MS Edge.

Il principio è il seguente. Raccogli 2 punti MouseEvent distanti. Ogni evento del mouse viene fornito con coordinate dello schermo e del documento. Misurare la distanza tra i 2 punti in entrambi i sistemi di coordinate. Sebbene ci siano offset fissi variabili tra i sistemi di coordinate a causa dei mobili del browser, la distanza tra i punti dovrebbe essere identica se la pagina non viene ingrandita. Il motivo per specificare "molto distanti" (ho messo questo come 12 pixel) è che sono rilevabili piccoli cambiamenti di zoom (ad esempio 90% o 110%).

Riferimento: https://developer.mozilla.org/en/docs/Web/Events/mousemove

passi:

  1. Aggiungi un listener di spostamento del mouse

    window.addEventListener("mousemove", function(event) {
        // handle event
    });
  2. Cattura 4 misurazioni dagli eventi del mouse:

    event.clientX, event.clientY, event.screenX, event.screenY
  3. Misurare la distanza d_c tra i 2 punti nel sistema client

  4. Misura la distanza d_s tra i 2 punti nel sistema dello schermo

  5. Se d_c! = D_s viene applicato lo zoom. La differenza tra i due indica la quantità di zoom.

NB Effettuare i calcoli della distanza solo raramente, ad esempio quando è possibile campionare un nuovo evento del mouse che è lontano dal precedente.

Limitazioni: si presume che l'utente sposterà il mouse almeno un po 'e lo zoom è inconoscibile fino a questo momento.


1
Ho creato un violino: jsfiddle.net/Terite/9b6ko854 con "lontano" significa 100 pixel. Sfortunatamente funziona instabile su Firefox (52) su MacBook con display retina. Va inoltre notato che lo zoom dell'interfaccia di Windows 7 125% viene rilevato in Chrome, Firefox e IE11 (nello zoom 125% che è predefinito quindi) come zoom del browser.
Terite,

Il tuo violino funziona per me, testato su Linux con Firefox e Chrome :)
user1191311

I display Retina aggiungono un altro livello di difficoltà perché segnalano erroneamente le dimensioni dei pixel, tra le altre cose.
user1191311

5

È possibile utilizzare l' API di Visual Viewport :

window.visualViewport.scale;

È standard e funziona sia su desktop che su dispositivo mobile: supporto browser .


Sembra pratico, ma è ancora disabilitato per impostazione predefinita nel desktop di Firefox e non funziona in Internet Explorer dal 31/05/20.
derekbaker783

3

In Internet Explorer 7, 8 e 9, funziona:

function getZoom() {
    var screen;

    screen = document.frames.screen;
    return ((screen.deviceXDPI / screen.systemXDPI) * 100 + 0.9).toFixed();
}

Viene aggiunto "+0.9" per evitare errori di arrotondamento (altrimenti, si otterrebbero 104% e 109% quando lo zoom del browser è impostato rispettivamente su 105% e 110%).

In IE6 lo zoom non esiste, quindi non è necessario controllare lo zoom.


1
Interessante. Per me, mostra sempre l'80% dello zoom ... Credo che ciò sia dovuto al fatto che ho impostato caratteri di grandi dimensioni a livello di Windows 7 (cerca "dimensione carattere" nel pannello di controllo). È meglio della soluzione IE8 nella risposta di @ yonran che non ha funzionato affatto per me. jsbin.com/obowof
ripper234

Ricevo il 101% quando lo zoom è impostato al 100%.
Allen Wallace,

anch'io. usa 0.4999 invece di 0.9
yan bellavance,

ieZoomLevel = ((screen.deviceXDPI / screen.systemXDPI) * 100 + 0.4999) .toFixed ();
yan bellavance,

3

Quello che mi è venuto in mente è:

1) Crea un position:fixed <div>con width:100%( id = zoomdiv )

2) quando la pagina viene caricata:

zoomlevel=$("#zoomdiv").width()*1.0 / screen.availWidth

E ha funzionato per me ctrl+e per lo ctrl-zoom.

oppure posso aggiungere la linea a un $(window).onresize()evento per ottenere il livello di zoom attivo


Codice:

<script>
    var zoom=$("#zoomdiv").width()*1.0 / screen.availWidth;

    $(window).resize(function(){
        zoom=$("#zoomdiv").width()*1.0 / screen.availWidth;
        alert(zoom);    
    });
</script>
<body>
    <div id=zoomdiv style="width:100%;position:fixed;"></div>
</body>

PS: questo è il mio primo post, scusate tutti gli errori


3
Sfortunatamente, questo funzionerà solo se l'utente ha il browser ingrandito ( screen.availWidthriporta la larghezza dello schermo in pixel dello schermo, non la finestra del browser).
Bailey Parker,

3

Questo ha funzionato perfettamente per me nei browser basati su webkit (Chrome, Safari):

function isZoomed() {
    var width, mediaQuery;

    width = document.body.clientWidth;
    mediaQuery = '(max-width: ' + width + 'px) and (min-width: ' + width + 'px)';

    return !window.matchMedia(mediaQuery).matches;
}

Non sembra funzionare in Firefox però.

Questo funziona anche in WebKit:

var zoomLevel = document.width / document.body.clientWidth;

5
document.widthritorna indefinito
Adam,

Restituisce sempre vero indipendentemente dallo zoom (2017, feb, display retina).
Tiberiu-Ionuț Stan,

3

Fondamentalmente, abbiamo:

  • window.devicePixelRatioche tiene conto sia dello zoom a livello di browser * sia dello zoom del sistema / densità dei pixel.
    * - su Mac / Safari il livello di zoom non viene preso in considerazione
  • query multimediali
  • vw/ vhUnità CSS
  • resize L'evento, che viene attivato al cambio del livello di zoom, causa la dimensione effettiva delle modifiche alla finestra

dovrebbe essere sufficiente per la normale UX. Se devi rilevare il livello di zoom che potrebbe essere un segno di cattiva progettazione dell'interfaccia utente.

Lo zoom del passo è più difficile da tracciare e non è attualmente considerato.


1
window.devicePixelRatio è una buona risposta che funziona nell'ultima versione dei principali browser: Chrome, Safari, FF, Edge, IE
DShultz

@kirilloid hai trovato qualcosa che potesse essere utilizzato per trovare in modo affidabile il "livello di zoom" in Safari?
onassar,


1

I tuoi calcoli sono ancora basati su un numero di pixel CSS. Ora hanno solo dimensioni diverse sullo schermo. Questo è il punto dello zoom a pagina intera.

Cosa vorresti che accadesse su un browser su un dispositivo a 192 dpi che quindi normalmente visualizzava quattro pixel del dispositivo per ogni pixel di un'immagine? Con uno zoom del 50% questo dispositivo ora visualizza un pixel dell'immagine in un pixel del dispositivo.


@Neil: come posso ottenere le dimensioni dei "pixel CSS"?
Comprendere il

I valori predefiniti CSS sono i punti, ma puoi ovviamente specificare i pixel usando il modificatore di dimensione px. Per quanto riguarda le proprietà degli elementi recuperate in JavaScript, queste dovrebbero già essere in pixel CSS. Quindi, se specifichi che la larghezza di un <div> è 100px, è quello che otterrai da JavaScript, qualunque sia il livello di zoom.
Neil,

1

Su Chrome

var ratio = (screen.availWidth / document.documentElement.clientWidth);
var zoomLevel = Number(ratio.toFixed(1).replace(".", "") + "0");

1
Funziona solo quando la finestra del browser ha l'intera larghezza dello schermo.
Tenbits

0

Non ho provato questo per IE, ma se si crea un elemento elemcon

min-width: 100%

poi

window.document.width / elem.clientWidth

ti fornirà il livello di zoom del tuo browser (incluso il document.body.style.zoomfattore).


Ho provato questo, ma lo zoom non sembra aumentare elem.clientWidth
Tom

0

Questo è per Chrome , sulla scia della risposta dell'utente 800583 ...

Ho trascorso alcune ore su questo problema e non ho trovato un approccio migliore, ma:

  • Ci sono 16 'zoomLevel' e non 10
  • Quando Chrome è a schermo intero / ingrandito, il rapporto è window.outerWidth/window.innerWidth, e quando non lo è, il rapporto sembra essere (window.outerWidth-16)/window.innerWidth, tuttavia il primo caso può essere affrontato dal secondo.

Quindi sono arrivato al seguente ...

Ma questo approccio presenta dei limiti: ad esempio se si suona la fisarmonica con la finestra dell'applicazione (ingrandimento rapido e riduzione della larghezza della finestra), si otterranno spazi vuoti tra i livelli di zoom sebbene lo zoom non sia cambiato (potrebbe essere outerWidth e innerWidth non lo sono esattamente aggiornato allo stesso tempo).

var snap = function (r, snaps)
{
    var i;
    for (i=0; i < 16; i++) { if ( r < snaps[i] ) return i; }
};
var w, l, r;
w = window.outerWidth, l = window.innerWidth;
return snap((w - 16) / l,
            [ 0.29, 0.42, 0.58, 0.71, 0.83, 0.95, 1.05, 1.18, 1.38, 1.63, 1.88, 2.25, 2.75, 3.5, 4.5, 100 ],
);

E se vuoi il fattore:

var snap = function (r, snaps, ratios)
{
    var i;
    for (i=0; i < 16; i++) { if ( r < snaps[i] ) return eval(ratios[i]); }
};
var w, l, r;
w = window.outerWidth, l = window.innerWidth;
return snap((w - 16) / l,
            [ 0.29, 0.42, 0.58, 0.71, 0.83, 0.95, 1.05, 1.18, 1.38, 1.63, 1.88, 2.25, 2.75, 3.5, 4.5, 100 ],
            [ 0.25, '1/3', 0.5, '2/3', 0.75, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2, 2.5, 3, 4, 5 ]
);

Ho avuto problemi con "window.outerWidth / window.innerWidth" che mi ha dato anche il valore sbagliato e che potrebbe essere stato perché ero in un iframe. Quindi quello che ho fatto è stato usare la finestra principale e mi ha dato la risposta corretta: window.parent.window.outerWidth / window.parent.window.innerWidth
yan bellavance

0

Ho questa soluzione solo per dispositivi mobili (testata con Android):

jQuery(function($){

zoom_level = function(){

    $("body").prepend('<div class="overlay" ' +
                'style="position:fixed; top:0%; left:0%; ' +
                'width:100%; height:100%; z-index:1;"></div>');

    var ratio = $("body .overlay:eq(0)").outerWidth() / $(window).width();
    $("body .overlay:eq(0)").remove();

    return ratio;
}

alert(zoom_level());

});

Se vuoi il livello di zoom subito dopo lo spostamento del pizzico, probabilmente dovrai impostare un po 'di timeout a causa del ritardo di rendering (ma non sono sicuro perché non l'ho provato).


0

Questa risposta si basa sui commenti di DevicePixelRatio che ritornano erroneamente sulla risposta dell'utente 1080381.

Ho scoperto che questo comando tornava in modo errato anche in alcuni casi quando si lavora con un desktop, Surface Pro 3 e Surface Pro 4.

Quello che ho scoperto è che ha funzionato sul mio desktop, ma SP3 e SP4 stavano dando numeri diversi l'uno dall'altro e dal desktop.

Ho notato, tuttavia, che SP3 stava tornando come 1 e mezzo volte il livello di zoom che mi aspettavo. Quando ho dato un'occhiata alle impostazioni di visualizzazione, SP3 era effettivamente impostato su 150% anziché sul 100% che avevo sul desktop.

Quindi, la soluzione ai commenti dovrebbe essere quella di dividere il livello di zoom restituito per la scala della macchina su cui ci si trova attualmente.

Sono stato in grado di ottenere la scala nelle impostazioni di Windows procedendo come segue:

ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DesktopMonitor");
double deviceScale = Convert.ToDouble(searcher.Get().OfType<ManagementObject>().FirstOrDefault()["PixelsPerXLogicalInch"]);
int standardPixelPerInch = 96;
return deviceScale / standardPixelPerInch;

Quindi nel caso del mio SP3, ecco come appare questo codice al 100% di zoom:

devicePixelRatio = 1.5
deviceScale = 144
deviceScale / standardPixelPerInch = 1.5
devicePixelRatio / (deviceScale / standardPixelPerInch) = 1

Moltiplicando per il 100 nella risposta originale dell'utente1080381 si otterrebbe uno zoom di 100 (%).


0

Se funziona attualmente, è comunque necessario separarlo dal browser. Testato con successo su Chrome (75) e Safari (11.1) (non ho ancora trovato la strada per FF). Inoltre, ottiene il valore di zoom corretto sul display retina e i calcoli vengono attivati ​​in caso di ridimensionamento.

    private pixelRatio() {
      const styleString = "(min-resolution: 2dppx), (-webkit-min-device-pixel-ratio: 1.5),(-moz-min-device-pixel-ratio: 1.5),(min-device-pixel-ratio: 1.5)";
      const chromeRatio = (Math.round((this.window.outerWidth / this.window.innerWidth)*100) / 100);
      const otherRatio = (Math.round(window.devicePixelRatio * 100) / 100);
      const resizeValue = (this.isChrome()) ? chromeRatio : otherRatio;

      return resizeValue || (this.window.matchMedia && this.window.matchMedia(styleString).matches ? 2 : 1) || 1;
    }


  private isChrome():boolean {
    return (!!this.window.chrome && !(!!this.window.opera || this.window.navigator.userAgent.indexOf(' Opera') >= 0))
  }

  private chrome() {
    const zoomChrome = Math.round(((this.window.outerWidth) / this.window.innerWidth)*100) / 100;
    return {
      zoom: zoomChrome,
      devicePxPerCssPx: zoomChrome1 * this.pixelRatio()
    };
  }

-1

qui non cambia !:

<html>
 <head>
  <title></title>
 </head>
<body>
 <div id="xy" style="width:400px;">
  foobar
 </div>
 <div>
  <button onclick="alert(document.getElementById('xy').style.width);">Show</button>
 </div>
</body>
</html>

crea un semplice file html, fai clic sul pulsante. indipendentemente dal livello di zoom: ti mostrerà la larghezza di 400 px (almeno con Firefox e ie8)


@tfl: è perché hai fissato la larghezza in stile in linea. Ho modificato il tuo campione per mostrare il mio caso (pubblicato nella domanda originale).
Comprendere il

-1

Questo può o non può aiutare nessuno, ma avevo una pagina che non riuscivo a centrare correttamente, indipendentemente dai trucchi Css che ho provato, quindi ho scritto una pagina del call center del file JQuery:

Il problema si verificava con il livello di zoom del browser, la pagina si spostava in base al 100%, 125%, 150%, ecc.

Il codice seguente si trova in un file JQuery chiamato centerpage.js.

Dalla mia pagina ho dovuto collegarmi a JQuery e questo file per farlo funzionare, anche se la mia pagina principale aveva già un collegamento a JQuery.

<title>Home Page.</title>
<script src="Scripts/jquery-1.7.1.min.js"></script>
<script src="Scripts/centerpage.js"></script>

centerpage.js:

// centering page element
function centerPage() {
    // get body element
    var body = document.body;

    // if the body element exists
    if (body != null) {
        // get the clientWidth
        var clientWidth = body.clientWidth;

        // request data for centering
        var windowWidth = document.documentElement.clientWidth;
        var left = (windowWidth - bodyWidth) / 2;

        // this is a hack, but it works for me a better method is to determine the 
        // scale but for now it works for my needs
        if (left > 84) {
            // the zoom level is most likely around 150 or higher
            $('#MainBody').removeClass('body').addClass('body150');
        } else if (left < 100) {
            // the zoom level is most likely around 110 - 140
            $('#MainBody').removeClass('body').addClass('body125');
        }
    }
}


// CONTROLLING EVENTS IN jQuery
$(document).ready(function() {
    // center the page
    centerPage();
});

Inoltre, se si desidera centrare un pannello:

// centering panel
function centerPanel($panelControl) {
    // if the panel control exists
    if ($panelControl && $panelControl.length) {
        // request data for centering
        var windowWidth = document.documentElement.clientWidth;
        var windowHeight = document.documentElement.clientHeight;
        var panelHeight = $panelControl.height();
        var panelWidth = $panelControl.width();

        // centering
        $panelControl.css({
            'position': 'absolute',
            'top': (windowHeight - panelHeight) / 2,
            'left': (windowWidth - panelWidth) / 2
        });

        // only need force for IE6
        $('#backgroundPanel').css('height', windowHeight);
    }
}

-1

Questa domanda è stata posta come un tempo, ma oggi, quando cercavo la stessa risposta "Come rilevare lo zoom in e out", non sono riuscito a trovare una risposta adatta a tutti i browser.

Come ora: per Firefox / Chrome / IE8 e IE9, lo zoom avanti e indietro genera un evento window.resize. Questo può essere catturato usando:

$(window).resize(function() {
//YOUR CODE.
});

-1

Una soluzione alternativa per FireFox 16+ per trovare DPPX (livello di zoom) esclusivamente con JavaScript:

var dppx = (function (precision) {
  var searchDPPX = function(level, min, divisor) {
    var wmq = window.matchMedia;
    while (level >= min && !wmq("(min-resolution: " + (level/divisor) + "dppx)").matches) {
      level--;
    }
    return level;
  };

  var maxDPPX = 5.0; // Firefox 22 has 3.0 as maximum, but testing a bit greater values does not cost much
  var minDPPX = 0.1; // Firefox 22 has 0.3 as minimum, but testing a bit smaller values does not cost anything
  var divisor = 1;
  var result;
  for (var i = 0; i < precision; i++) {
    result = 10 * searchDPPX (maxDPPX, minDPPX, divisor);
    maxDPPX = result + 9;
    minDPPX = result;
    divisor *= 10;
  }

  return result / divisor;
}) (5);

Non funziona come previsto in Firefox (52) su MacBook con display Retina - restituisce 2 quando non è in zoom. Ho creato un violino: jsfiddle.net/Terite/wadkh3ea
Terite

-1
function supportFullCss3()
{
    var div = document.createElement("div");
    div.style.display = 'flex';
    var s1 = div.style.display == 'flex';
    var s2 = 'perspective' in div.style;

    return (s1 && s2);
};

function getZoomLevel()
{
    var screenPixelRatio = 0, zoomLevel = 0;

    if(window.devicePixelRatio && supportFullCss3())
        screenPixelRatio = window.devicePixelRatio;
    else if(window.screenX == '0')
        screenPixelRatio = (window.outerWidth - 8) / window.innerWidth;
    else
    {
        var scr = window.frames.screen;
        screenPixelRatio = scr.deviceXDPI / scr.systemXDPI;
    }

    //---------------------------------------
    if (screenPixelRatio <= .11){ //screenPixelRatio >= .01 &&
      zoomLevel = "-7";
    } else if (screenPixelRatio <= .25) {
      zoomLevel = "-6";
    }else if (screenPixelRatio <= .33) {
      zoomLevel = "-5.5";
    } else if (screenPixelRatio <= .40) {
      zoomLevel = "-5";
    } else if (screenPixelRatio <= .50) {
      zoomLevel = "-4";
    } else if (screenPixelRatio <= .67) {
      zoomLevel = "-3";
    } else if (screenPixelRatio <= .75) {
      zoomLevel = "-2";
    } else if (screenPixelRatio <= .85) {
      zoomLevel = "-1.5";
    } else if (screenPixelRatio <= .98) {
      zoomLevel = "-1";
    } else if (screenPixelRatio <= 1.03) {
      zoomLevel = "0";
    } else if (screenPixelRatio <= 1.12) {
      zoomLevel = "1";
    } else if (screenPixelRatio <= 1.2) {
      zoomLevel = "1.5";
    } else if (screenPixelRatio <= 1.3) {
      zoomLevel = "2";
    } else if (screenPixelRatio <= 1.4) {
      zoomLevel = "2.5";
    } else if (screenPixelRatio <= 1.5) {
      zoomLevel = "3";
    } else if (screenPixelRatio <= 1.6) {
      zoomLevel = "3.3";
    } else if (screenPixelRatio <= 1.7) {
      zoomLevel = "3.7";
    } else if (screenPixelRatio <= 1.8) {
      zoomLevel = "4";
    } else if (screenPixelRatio <= 1.9) {
      zoomLevel = "4.5";
    } else if (screenPixelRatio <= 2) {
      zoomLevel = "5";
    } else if (screenPixelRatio <= 2.1) {
      zoomLevel = "5.2";
    } else if (screenPixelRatio <= 2.2) {
      zoomLevel = "5.4";
    } else if (screenPixelRatio <= 2.3) {
      zoomLevel = "5.6";
    } else if (screenPixelRatio <= 2.4) {
      zoomLevel = "5.8";
    } else if (screenPixelRatio <= 2.5) {
      zoomLevel = "6";
    } else if (screenPixelRatio <= 2.6) {
      zoomLevel = "6.2";
    } else if (screenPixelRatio <= 2.7) {
      zoomLevel = "6.4";
    } else if (screenPixelRatio <= 2.8) {
      zoomLevel = "6.6";
    } else if (screenPixelRatio <= 2.9) {
      zoomLevel = "6.8";
    } else if (screenPixelRatio <= 3) {
      zoomLevel = "7";
    } else if (screenPixelRatio <= 3.1) {
      zoomLevel = "7.1";
    } else if (screenPixelRatio <= 3.2) {
      zoomLevel = "7.2";
    } else if (screenPixelRatio <= 3.3) {
      zoomLevel = "7.3";
    } else if (screenPixelRatio <= 3.4) {
      zoomLevel = "7.4";
    } else if (screenPixelRatio <= 3.5) {
      zoomLevel = "7.5";
    } else if (screenPixelRatio <= 3.6) {
      zoomLevel = "7.6";
    } else if (screenPixelRatio <= 3.7) {
      zoomLevel = "7.7";
    } else if (screenPixelRatio <= 3.8) {
      zoomLevel = "7.8";
    } else if (screenPixelRatio <= 3.9) {
      zoomLevel = "7.9";
    } else if (screenPixelRatio <= 4) {
      zoomLevel = "8";
    } else if (screenPixelRatio <= 4.1) {
      zoomLevel = "8.1";
    } else if (screenPixelRatio <= 4.2) {
      zoomLevel = "8.2";
    } else if (screenPixelRatio <= 4.3) {
      zoomLevel = "8.3";
    } else if (screenPixelRatio <= 4.4) {
      zoomLevel = "8.4";
    } else if (screenPixelRatio <= 4.5) {
      zoomLevel = "8.5";
    } else if (screenPixelRatio <= 4.6) {
      zoomLevel = "8.6";
    } else if (screenPixelRatio <= 4.7) {
      zoomLevel = "8.7";
    } else if (screenPixelRatio <= 4.8) {
      zoomLevel = "8.8";
    } else if (screenPixelRatio <= 4.9) {
      zoomLevel = "8.9";
    } else if (screenPixelRatio <= 5) {
      zoomLevel = "9";
    }else {
      zoomLevel = "unknown";
    }

    return zoomLevel;
};

6
Spiega gentilmente anche come funziona il tuo codice. Ciò sarà utile se un novizio trova la tua risposta.
displayName

Ho creato un violino: jsfiddle.net/Terite/5n1bk9do As @AlexeySh. menzionato, non funziona come previsto sul display Retina in Chrome (56), Firefox (52). Mostra anche 0 in zoom su Safari (10).
Terite,

-1

Il problema risiede nei tipi di monitor utilizzati, un monitor 4K rispetto al monitor standard. Chrome è di gran lunga il più intelligente nel dirci qual è il livello di zoom semplicemente usando window.devicePixelRatio, apparentemente può dire qual è la densità dei pixel e riporta lo stesso numero per qualunque cosa.

Altri browser, non così tanto. IE e Edge sono probabilmente i peggiori, poiché gestiscono i livelli di zoom in modo molto diverso. Per ottenere lo stesso testo di dimensioni su un monitor 4K, è necessario selezionare il 200%, anziché il 100% su un monitor standard.

A partire da maggio 2018, ecco cosa devo rilevare i livelli di zoom per alcuni dei browser più popolari, Chrome, Firefox e IE11. Devo dirmi qual è la percentuale di zoom. Per IE, riporta il 100% anche per i monitor 4K che sono effettivamente al 200%, ma la dimensione del testo è davvero la stessa.

Ecco un violino: https://jsfiddle.net/ae1hdogr/

Se qualcuno si preoccupasse di prendere a pugni gli altri browser e aggiornare il violino, allora per favore fallo. Il mio obiettivo principale era coprire questi 3 browser per rilevare se le persone utilizzavano un fattore di zoom superiore al 100% per utilizzare la mia applicazione Web e visualizzare un avviso che suggeriva un fattore di zoom minore.


Safari su Mac Book Pro (schermo retina) restituisce 0, Chrome su schermo non retina restituisce correttamente sembra 100, 90 ecc.
OZZIE

Restituisce 200 sullo schermo Retina di Chrome e Firefox
OZZIE,
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.