Nein, eigentlich nicht.
Meine erste Vermutung war, dass dies absichtlich nicht in Browsern verfügbar gemacht wurde, weil Browser absichtlich nicht wollen, dass wir uns damit herumschlagen – oder gut gemeinte, aber schlecht ausgehende Entscheidungen auf Basis dieser Informationen treffen. Aber ich sehe dafür keine Beweise.
StackOverflow-Antworten zeigen, wie seltsam browserspezifisch das sein kann. Dieses Skript von 2013 funktioniert für mich in Chrome, aber überhaupt nicht in Safari und meldet in Firefox falsche Ergebnisse. Selbst wenn dieses Skript funktionieren würde, basiert es auf User-Agent-Erkennung (die nicht mehr lange existieren wird) und einigen unglaublich seltsamen Hacks.
Bitte korrigieren Sie mich, wenn ich falsch liege, aber ich denke, die Antwort ist, dass wir das im Moment nicht wirklich tun können.
Es gibt die Visual Viewport API
Ich bin irgendwie verwirrt davon.
- Die Spezifikation ist ein Entwurf
- Die Kompatibilitätstabelle listet viel Unterstützung auf
window.visualViewportist in Firefox, Safari und Chrome (Desktop) definiert- Aber…
window.visualViewport.scaleist in Safari und Chrome immer1und in Firefoxundefined. Mit anderen Worten: nutzlos.
Ich weiß nicht genau, ob das die Browser-Zoomstufe *genau* darstellen soll, denn die Spezifikation spricht speziell über Pinch-Zoom. Es ist also vielleicht einfach nicht für Desktop-Browser-Zoomstufen gedacht.
Was ist ein Anwendungsfall hierfür?
Ein Kerl hat mir eine Situation wie diese geschildert
Er wollte CSS Grid verwenden, um Friedhofsflächen (schon interessant) wie einen von oben nach unten gerichteten Grundriss eines Friedhofs zu gestalten. Es gab viele Informationen im Layout. Wenn man "herausgezoomt" war, um den gesamten Friedhof auf einer Seite zu sehen, war der Text in jedem Bereich zu klein zum Lesen (da die Schriftgröße so eingestellt war, dass sie in die Kästchen/Gräber passte). Idealerweise würde die Seite diesen Text ausblenden, wenn der Browser herausgezoomt ist (vielleicht eine Klasse .hide-text). Wenn man weit genug hineingezoomt hat, wird der Text wieder angezeigt.
Wie zum Beispiel...
// Dunno if "resize" is best. I don't know what the "change zoom" event would be
window.visualViewport.addEventListener("resize", viewportHandler);
function viewportHandler(event) {
// NOTE: This doesn't actually work at time of writing
if (event.target.scale > 3) {
document.body.classList.remove("hide-text");
} else {
document.body.classList.add("hide-text");
}
}
Es gibt die Pixeldichte...
Ben Nadel hat kürzlich gebloggt: Betrachtung, wie der Browser-Zoom CSS-Medienabfragen und Pixeldichte beeinflusst.
Wenn man sich window.devicePixelRatio ansieht und hineinzoomt, erhöht sich die Pixeldichte in Chrome und Firefox beim Hineinzoomen und verringert sich beim Herauszoomen. Theoretisch könnte man den ursprünglichen Wert testen (er könnte für Benutzer mit unterschiedlichen Bildschirmen an verschiedenen Stellen beginnen) und Änderungen dieses Wertes verwenden, um den Zoom zu erraten. *Aber…* in Safari tut sich nichts, d. h., er bleibt unabhängig vom Zoom gleich. Außerdem kann die Zoomstufe des Betriebssystems hier Dinge beeinflussen, was es noch komplizierter macht; ganz zu schweigen davon, dass eine Seite *mit einer bereits vorhandenen Zoomstufe* beginnen könnte, was die gesamte Berechnung von Anfang an durcheinanderbringen könnte.
Naja, ich wollte gerade schlafen gehen... dann habe ich das gelesen... war sicher, dass es eine Antwort gab. Habe es versucht und dann erkannt: "Nein, das geht nicht". Ich habe versucht, spezifische Verhältnisse zwischen Bildschirmbreite und Fensterbreite zu testen... was bei Vollbild auf Chrome funktioniert, aber da IE und Firefox die Bildschirmgröße zusammen mit der Fenstergröße skalieren, gibt es keine Möglichkeit, den Unterschied zu erkennen. Entschuldigen Sie Rechtschreibfehler und überladenen Code... es ist 2 Uhr morgens.
Zum jetzigen Zeitpunkt würde ich den Browser-Zoom einfach verhindern, indem ich Maus- und Tastaturereignisse innerhalb des Zielcontainers abhöre und benutzerdefiniertes Zoomen (z.B. transform scale) innerhalb dieser Ereignisse implementiere. Nur dann haben Sie die volle Kontrolle über die Browser hinweg.
Meiner Meinung nach wäre das ein Fall, in dem Sie eine JavaScript-Bibliothek verwenden möchten, die einen Z-Achsen-Scroll-/Zoommechanismus implementiert, anstatt den nativen Browser-Zoom zu verwenden.
Ja, für diesen Anwendungsfall stimme ich voll und ganz zu.
Ich habe einen ähnlichen Anwendungsfall, bei dem ich versuche, Folgendes herauszufinden: Viele neuere Laptops haben hochauflösende Bildschirme und gute Auflösungen, aber sie skalieren die Dinge auf Betriebssystemebene von Haus aus auf das Äquivalent von weniger als 1024×768. Ich versuche, einen Weg zu finden, diese Skalierung für einige Komponenten unserer Webanwendung umzukehren, damit Dinge, die normalerweise passen würden, immer noch passen.
Haben Sie jemals eine Lösung dafür gefunden? Wir haben das gleiche Problem, hatten noch nie einen Kunden damit, aber er betrachtet alles mit 150% auf Betriebssystemseite, und das ruiniert unsere Layouts! Gibt es eine Möglichkeit, dies zu begrenzen oder zu verhindern?
window.visualViewport.scale ändert sich, wenn Sie Pinch-Zoom auf Tablets und Laptops verwenden, das ist ein anderes Verhalten.
Ich bin mir nicht sicher, ob ich das Problem richtig verstehe, aber könnten Sie nicht eine Medienabfrage in JS verwenden, um zu sehen, ob die Breite des Dokuments mit der Medienabfrage übereinstimmt, um zu erkennen, ob der Benutzer hineingezoomt hat oder nicht?
Zum Beispiel:
Ändern Sie die Größe Ihres Browserfensters auf 800 Pixel Breite.
Führen Sie dieses JS in den Entwicklertools aus:
window.matchMedia('(min-width: 800px)')(Es sollte "true" für "matches" melden.)Zoomen Sie hinein.
Führen Sie dasselbe JS aus. (Es sollte "false" für "matches" melden.)
Um den Zoomfaktor zu erkennen, müssten Sie nur den Unterschied zwischen der Dokumentbreite und dem Zeitpunkt, zu dem die Medienabfrage wieder übereinstimmt, betrachten.
Erster Weg, um das Nichtwissen des Browser-Zoomfaktors zu umgehen, ist die Verwendung von CSS, um den
zoombasierend auf dem Zustand einesradio-Inputs zuzuweisen. Hier ist ein schnelles Beispiel, das die Captions-Texte ausblendet, wenn die Zoomstufe25%ausgewählt ist...... Überprüfung von CanIUse — Zoom besagt, dass
zoomvon Firefox, Opera Mini und KaiOS **nicht** unterstützt wird.Allerdings ist nicht alles verloren, denn wie eine Antwort auf StackOverflow — imitate browser zoom with JavaScript vorschlägt, besteht die zweite Methode darin, stattdessen
transform: scale(/*...*/)zusammen mit einigen anderen Eigenschaften zu verwenden, z.B. ...Obwohl diese Beispiele den Zoomfaktor nicht erkennen, sind es betriebliche Workarounds, alle ohne JavaScript, und wenn Sie JavaScript-Ereignis-Listener wünschen, ist es nicht übermäßig schwierig, sie zu Radio-Inputs hinzuzufügen.
Nachdem ich mehrere frustrierende Stunden mit diesem Problem verbracht habe, bin ich widerwillig zu dem Schluss gekommen, dass es auf dem Desktop nicht möglich ist, den Zoomfaktor zuverlässig auszulesen, da W3C und die Browser-Anbieter harmonisch zusammengearbeitet haben, um das Viewport-System komplett zu verhunzen. Auf Mobilgeräten IST es möglich.
Erstens gibt window.visualViewport.scale die Zoomstufe in unterstützten Browsern (Chromium-basierte + Firefox Android + Safari iOS) an, aber NUR, wenn Sie Pinch-Zoom verwenden. Bei Seitenzoom bleibt er immer bei 1, wie Sie gesehen haben. Offensichtlich.
Auf MOBILEN Browsern, die die Skalierung nicht unterstützen, verwenden Sie diese Berechnung, die funktioniert
screen.width / ((window.visualViewport && window.visualViewport.width) || window.innerWidth)
Auf Desktop-Browsern vergessen Sie es. Scale funktioniert nicht mit Seitenzoom. window.devicePixelRatio funktioniert zwar mit Seitenzoom, aber nicht mit Pinch-Zoom. Außerdem müssten Sie den Wert durch das tatsächliche physische DPR des Systems teilen, das nirgends in JavaScript gefunden werden kann, da dies den Hinweis geben würde.
Für den Anwendungsfall Ihres Freundes empfehle ich Folgendes
1) Wählen Sie einen Friedhofsplot als Referenzelement und lesen Sie dessen offsetWidth einmal aus.
2) Vergleichen Sie diesen Wert mit window.innerWidth und entscheiden Sie, ob der Benutzer hinein- oder herausgezoomt hat, um den Text ein- oder auszublenden.
3) Idealerweise wiederholen Sie dies bei jedem Größenänderungsereignis. Leider sind Größenänderungsereignisse sowohl auf Mobil- als auch auf Desktop-Browsern unzuverlässig, denn warum sollte man sie zuverlässig machen? Fügen Sie vielleicht auch ein Scroll-Ereignis hinzu und vielleicht ein Poll-Skript, das alle zwei Sekunden oder so nachsieht.
Nachtrag zu meinem vorherigen Kommentar: Die Formel, die ich für mobile Browser angebe, funktioniert nur, wenn Sie meta width=device-width verwenden.
Ich konnte den Text-Zoom schon seit einiger Zeit per JS erkennen: Wenn ein Text-Zoom stattfindet, füge ich dem Tag eine Klasse hinzu, damit ich die Seite so stylen kann, dass der gezoomte Text immer noch lesbar ist. Eine Demo dazu finden Sie hier
https://www.useragentman.com/enable/hero-image-text-resize.php
Natürlich könnte dies missbraucht werden (z.B. wenn ein Text-Zoom stattfindet, könnte ein Entwickler CSS verwenden, um die Schrift kleiner zu machen, was niemals getan werden sollte) – aber wenn es korrekt verwendet wird, kann dies viele CSS-Probleme beheben, die bei Text-Zoom auftreten (und in meiner Karriere habe ich das oft gesehen).
Ich würde mich über Feedback zu dieser Bibliothek freuen, die auf GitHub verfügbar ist
https://github.com/zoltan-dulac/text-zoom-resize
(Zum Zeitpunkt des Schreibens gibt die oben verlinkte Enable-Seite noch keine ordnungsgemäßen npm-Informationen an. Sie wird bald aktualisiert, bis dahin verwenden Sie einfach den Link github.com für Informationen zur Installation des Pakets).
Ich musste kürzlich einen Weg finden, dies zu tun, und bin zu einer reinen CSS-Methode gelangt, die die Tatsache ausnutzt, dass sich der Wert eines
rembeim Text-Zoom ändert, der Wert einespxjedoch nicht.Also, wo
1rem16pxist, würde etwas wie......nicht bei Standardzoom angewendet werden, aber bei 200% Zoom zwischen 1170px und 2336px angewendet werden.
Kann JavaScript die Zoomstufe des Browsers erkennen?
In Chromium-basierten Browsern lautet die Antwort **ja**, solange die Version die Window API
getScreenDetailsunterstützt (verfügbar in Chrome seit v100, März 2022 – weitere Details finden Sie unter caniuse).Erhebliche Einschränkungen
Kann nur asynchron abgerufen werden.
Benutzer muss die Berechtigung "Fenster auf allen Ihren Displays verwalten" akzeptieren (dies ist offensichtlich ein ziemlich großer Punkt).