it-swarm.com.de

Wie erkennt man den Zoomfaktor der Seite in allen modernen Browsern?

  1. Wie kann ich die Zoomstufe der Seite in allen modernen Browsern erkennen? Während dieser Thread beschreibt, wie dies in IE7 und IE8 geschieht, kann ich keine gute Cross-Browser-Lösung finden.

  2. Firefox speichert die Zoomstufe der Seite für den zukünftigen Zugriff. Kann ich beim Laden der ersten Seite die Zoomstufe abrufen? Irgendwo, wo ich gelesen habe, funktioniert es, wenn eine Zoomänderung auftritt after die Seite wird geladen.

  3. Gibt es eine Möglichkeit, das 'zoom'-Ereignis abzufangen?

Ich brauche das, weil einige meiner Berechnungen pixelbasiert sind und beim Zoomen schwanken können.


Geändertes Beispiel von @tfl

Diese Seite zeigt beim Zoomen unterschiedliche Höhenwerte an. [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>
275
understack

Jetzt ist es ein noch größeres Durcheinander als damals, als diese Frage zum ersten Mal gestellt wurde. Nach dem Lesen aller Antworten und Blogeinträge, die ich finden konnte, hier eine Zusammenfassung. Ich habe auch diese Seite eingerichtet, um alle diese Methoden zum Messen der Zoomstufe zu testen .

Edit (2011-12-12): Ich habe ein Projekt hinzugefügt, das geklont werden kann: https://github.com/tombigel/detect-zoom

  • IE8: screen.deviceXDPI / screen.logicalXDPI (oder für die Zoomstufe relativ zum Standardzoom screen.systemXDPI / screen.logicalXDPI)
  • IE7: var body = document.body,r = body.getBoundingClientRect(); return (r.left-r.right)/body.offsetWidth; (Danke an dieses Beispiel oder diese Antwort )
  • FF3.5 NUR: screen.widthBildschirmbreite der Medienabfrage (siehe unten) (nutzt die Tatsache, dass screen.width Gerätepixel verwendet, MQ-Breite jedoch CSS-Pixel - dank Quirksmode widths )
  • _/FF3.6: keine bekannte Methode
  • FF4 +: Medien fragt binäre Suche ab (siehe unten)
  • WebKit: https://www.chromestatus.com/feature/5737866978131968 (Dank an Teo in den Kommentaren)
  • WebKit: Messen Sie die bevorzugte Größe eines div mit -webkit-text-size-adjust:none.
  • WebKit: (gebrochen seit r72591 ) document.width / jQuery(document).width() (Danke an Dirk van Oosterbosch oben ). Um das Verhältnis in Bezug auf die Gerätepixel zu erhalten (anstatt relativ zum Standardzoom), multiplizieren Sie mit window.devicePixelRatio.
  • Altes WebKit? (ungeprüft): parseInt(getComputedStyle(document.documentElement,null).width) / document.documentElement.clientWidth (von diese Antwort )
  • Opera: document.documentElement.offsetWidthBreite eines position:fixed; width:100% div. von hier aus ( Quirksmode's widths table sagt, es ist ein Fehler; innerWidth sollte CSS px sein). Wir verwenden das position: fixed Element, um die Breite des Viewports zu ermitteln einschließlich des Bereichs, in dem die Bildlaufleisten sind; document.documentElement.clientWidth schließt diese Breite aus. Dies ist seit einiger Zeit im Jahr 2011 kaputt; Ich kenne keine Möglichkeit mehr, die Zoomstufe in Opera zu erhalten.
  • _/Other: Flash-Lösung von Sebastian
  • Unzuverlässig: Hören Sie sich die Mausereignisse an und messen Sie die Änderungen in screenX/die Änderungen in clientX

Hier ist eine binäre Suche nach Firefox 4, da mir keine Variablen bekannt sind, an denen sie verfügbar ist:

<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>
261
yonran

Für mich, für Chrome/Webkit, funktionierte document.width / jQuery(document).width() nicht. Als ich mein Fenster verkleinert und so auf meine Website zoomte, dass horizontale Bildlaufleisten angezeigt wurden, war document.width / jQuery(document).width() beim Standardzoom nicht gleich 1. Dies liegt daran, dass document.width einen Teil des Dokuments außerhalb des Ansichtsfensters enthält.

Die Verwendung von window.innerWidth und window.outerWidth hat funktioniert. Aus irgendeinem Grund wird in Chrome die äußere Breite in Bildschirmpixeln und die innere Breite in CSS-Pixeln gemessen.

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";
}
44
user800583

Du kannst es versuchen

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

Dies gibt Ihnen die Zoom-Stufe Ihres Browsers. 

Um das Zoom-Ereignis zu erfassen, können Sie verwenden

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

Mein Kollege und ich haben das Skript von https://github.com/tombigel/detect-zoom verwendet. Darüber hinaus haben wir auch dynamisch ein svg -Element erstellt und dessen currentScale -Eigenschaft überprüft. Es funktioniert großartig in Chrome und wahrscheinlich auch den meisten Browsern. Bei FF muss jedoch die Funktion "Nur Text zoomen" deaktiviert werden. SVG ist in den meisten Browsern unterstützt . Zum Zeitpunkt dieses Schreibens getestet auf IE10, FF19 und 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);
15
Jay

Ich fand diesen Artikel enorm hilfreich. Vielen Dank an Yonran. Ich wollte einige zusätzliche Kenntnisse weitergeben, die ich bei der Implementierung einiger der von ihm bereitgestellten Techniken gefunden hatte. In FF6 und Chrome 9 wurde die Unterstützung für Medienabfragen von JS hinzugefügt, wodurch der für die Ermittlung des Zooms in FF erforderliche Abfrageansatz für Medien erheblich vereinfacht werden kann. Siehe die Dokumente unter MDN hier . Für meine Zwecke musste ich nur feststellen, ob der Browser ein- oder ausgezoomt war. Ich brauchte den tatsächlichen Zoomfaktor nicht. Ich konnte meine Antwort mit einer JavaScript-Zeile erhalten:

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

In Kombination mit den IE8 + - und Webkit-Lösungen, die auch Einzellinien waren, konnte ich die Zoomrate der meisten Browser erkennen, die mit nur wenigen Codezeilen auf unsere App trafen.

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

Das ist alles was du brauchst.

10
Alex von Thorn

Ich habe seit Januar 2016 eine Lösung dafür. Getestet in Chrome, Firefox und MS Edge-Browsern. 

Das Prinzip ist wie folgt. Sammeln Sie 2 weit voneinander entfernte MouseEvent-Punkte. Jedes Mausereignis wird mit Bildschirm- und Dokumentkoordinaten geliefert. Messen Sie den Abstand zwischen den beiden Punkten in beiden Koordinatensystemen. Zwar gibt es feste Versätze zwischen den Koordinatensystemen aufgrund der Browser-Einrichtung, der Abstand distance zwischen den Punkten sollte jedoch identisch sein, wenn die Seite nicht gezoomt wird. Der Grund für die Angabe von "weit auseinander" (ich setze dies auf 12 Pixel) ist, dass kleine Zoomänderungen (z. B. 90% oder 110%) erkennbar sind.

Referenz: https://developer.mozilla.org/de/docs/Web/Events/mousemove

Schritte: 

  1. Fügen Sie einen Mausbewegungslistener hinzu

    window.addEventListener("mousemove", function(event) {
        // handle event
    });
    
  2. Erfassen Sie 4 Messungen von Mausereignissen:

    event.clientX, event.clientY, event.screenX, event.screenY
    
  3. Messen Sie den Abstand d_c zwischen den zwei Punkten im Client-System

  4. Messen Sie den Abstand d_s zwischen den zwei Punkten im Bildschirmsystem

  5. Wenn d_c! = D_s, wird der Zoom angewendet. Der Unterschied zwischen den beiden Werten gibt den Zoomfaktor an.

N.B. Führen Sie die Entfernungsberechnungen nur selten durch, z. Wenn Sie ein neues Mausereignis ausprobieren können, das weit vom vorherigen entfernt ist.

Einschränkungen: Es wird davon ausgegangen, dass der Benutzer die Maus ein wenig bewegt, und bis zu diesem Zeitpunkt ist der Zoom nicht erkennbar.

5
user1191311

Dies hat bei webkit-basierten Browsern (Chrome, Safari) für mich gut funktioniert:

function isZoomed() {
    var width, mediaQuery;

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

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

Scheint aber nicht in Firefox zu funktionieren.

Das funktioniert auch in WebKit:

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

In Internet Explorer 7, 8 und 9 funktioniert das:

function getZoom() {
    var screen;

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

"+0,9" wird hinzugefügt, um Rundungsfehler zu vermeiden (andernfalls würden Sie 104% und 109% erhalten, wenn der Browser-Zoom auf 105% bzw. 110% eingestellt ist).

In IE6 ist kein Zoom vorhanden, sodass der Zoom nicht überprüft werden muss.

3
pench

Grundsätzlich haben wir:

  • window.devicePixelRatio, der sowohl Zoom auf Browser-Ebene * als auch System-Zoom/Pixeldichte berücksichtigt.
    * - Bei Mac/Safari wird die Zoomstufe nicht berücksichtigt
  • Medien-Anfragen
  • vwvh CSS-Einheiten
  • Ein resize -Ereignis, das bei einer Änderung der Zoomstufe ausgelöst wird, bewirkt eine effektive Änderung der Fenstergröße

das sollte für _/normal UX ausreichen. Wenn Sie die Zoomstufe ermitteln müssen, kann dies auf ein schlechtes Design der Benutzeroberfläche hindeuten.

Pitch-Zoom ist schwieriger zu verfolgen und wird derzeit nicht berücksichtigt.

2
kirilloid

Was ich mir ausgedacht habe ist:

1) Erstellen Sie einen position:fixed<div> mit width:100% ( id = zoomdiv )

2) wenn die Seite geladen wird:

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

Und es funktionierte für mich für ctrl+ und ctrl- Zooms.

oder ich kann die Zeile zu einem $(window).onresize() -Ereignis hinzufügen, um die aktive Zoomstufe zu erhalten


Code:

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

P.S. : das ist mein erster post, verzeihen sie alle fehler

2
Abhishek Borar

Auf mobile - Geräten (mit Chrome für Android oder Opera Mobile) können Sie den Zoom anhand von window.visualViewport.scale ..__ erkennen. https://developer.mozilla.org/en-US/docs/Web/API/Visual_Viewport_API

Auf Safari erkennen: document.documentElement.clientWidth/window.innerWidth (1 zurückgeben, wenn das Gerät nicht gezoomt wird).

2
JIm

Auf Chrome

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

Ihre Berechnungen basieren immer noch auf einer Reihe von CSS-Pixeln. Sie haben jetzt nur eine andere Größe auf dem Bildschirm. Das ist der Punkt, an dem der volle Seiten-Zoom möglich ist.

Was möchten Sie in einem Browser mit einem 192-dpi-Gerät, das normalerweise vier Gerätepixel für jedes Pixel in einem Bild anzeigt? Bei 50% Zoom zeigt dieses Gerät nun ein Bildpixel in einem Gerätepixel an.

1
Neil

Dies ist für Chrome, nach user800583 Antwort ...

Ich habe ein paar Stunden mit diesem Problem verbracht und habe keinen besseren Ansatz gefunden, aber:

  • Es gibt 16 'zoomLevel' und nicht 10
  • Wenn Chrome Vollbild/maximiert ist, lautet das Verhältnis window.outerWidth/window.innerWidth. Wenn dies nicht der Fall ist, scheint das Verhältnis (window.outerWidth-16)/window.innerWidth zu sein. Der 1. Fall kann jedoch durch den 2. Fall angesprochen werden.

Also kam ich zu folgendem ...

Dieser Ansatz hat jedoch Einschränkungen: Wenn Sie beispielsweise das Akkordeon mit dem Anwendungsfenster spielen (das Fenster schnell vergrößern und verkleinern), erhalten Sie Lücken zwischen den Zoomstufen, obwohl sich der Zoom nicht geändert hat (möglicherweise äußerliche Breite und innere Breite nicht) genau in derselben zeit aktualisiert).

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

Und wenn Sie den Faktor wollen:

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 ]
);
0
jeum

Diese Antwort basiert auf Kommentaren über devicePixelRatio, die falsch in der Antwort von user1080381 zurückgegeben werden.

Ich habe festgestellt, dass dieser Befehl in einigen Fällen auch bei der Arbeit mit einem Desktop, Surface Pro 3 und Surface Pro 4 falsch zurückgegeben wurde.

Was ich fand, ist, dass es auf meinem Desktop funktionierte, aber das SP3 und das SP4 gaben unterschiedliche Zahlen voneinander und vom Desktop an.

Ich bemerkte jedoch, dass das SP3 das 1,5-fache der von mir erwarteten Zoomstufe erreichte. Bei einem Blick auf die Anzeigeeinstellungen war das SP3 tatsächlich auf 150% anstelle der 100% auf meinem Desktop eingestellt.

Die Lösung für die Kommentare sollte also darin bestehen, die zurückgegebene Zoomstufe durch die Skala der Maschine zu teilen, auf der Sie sich gerade befinden.

Ich konnte die Skala in den Windows-Einstellungen abrufen, indem Sie folgende Schritte ausführen:

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

Im Falle meines SP3 sieht dieser Code also bei 100% Zoom aus:

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

Multiplizieren mit 100 in der ursprünglichen Antwort von Benutzer 1080381 würde dann einen Zoom von 100 (%) ergeben.

0
Cameron Weaver

Ich habe diese Lösung für nur für mobile Geräte (getestet mit 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());

});

Wenn Sie die Zoomstufe direkt nach dem Pinch verschieben möchten, müssen Sie wahrscheinlich wegen der Renderverzögerung ein kleines Timeout einstellen (aber ich bin mir nicht sicher, weil ich es nicht getestet habe).

0
pmrotule

Habe es zur Zeit funktioniert aber muss noch per Browser getrennt werden. Erfolgreich getestet auf Chrome (75) und Safari (11.1) (bisher noch kein Weg für FF gefunden). Außerdem wird der Zoomwert auf der Retina-Anzeige korrigiert und Berechnungen werden bei einem Größenänderungsereignis ausgelöst.

    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()
    };
  }
0
Yogi

Ich habe dies nicht für IE getestet, aber wenn Sie ein Element elem mit machen

min-width: 100%

dann 

window.document.width / elem.clientWidth

gibt Ihnen die Zoomstufe Ihres Browsers (einschließlich des document.body.style.zoom-Faktors).