351 votes

Comment détecter le niveau de zoom de la page dans tous les navigateurs modernes?

  1. Comment puis-je détecter le niveau de zoom de la page dans tous les navigateurs modernes? Bien que ce thread raconte comment le faire dans IE7 et IE8, je ne peux pas trouver une bonne solution de navigateur.

  2. Firefox stocke la page niveau de zoom pour un accès ultérieur. Le premier chargement de la page, serais-je en mesure d'obtenir le niveau de zoom? J'ai lu quelque part qu'il fonctionne quand un zoom changement se produit après le chargement de la page.

  3. Est-il un moyen de piéger l' 'zoom' événement?

J'ai besoin de cela parce que certains de mes calculs sont basés sur le pixel et ils peuvent fluctuer en gros plan.


Modifié échantillon donné par @tfl

Cette page alertes différentes valeurs de hauteur lorsque vous utilisez le zoom. [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>

296voto

yonran Points 6952

Il est maintenant encore plus de désordre que c'est lorsque cette question est posée. À la lecture de toutes les réponses et les messages de blog que j'ai pu trouver, voici un résumé. J'ai également mis en place cette page pour tester toutes ces méthodes de mesure du niveau de zoom.

Edit (2011-12-12): j'ai ajouté un projet qui peut être cloné: https://github.com/tombigel/detect-zoom

  • IE8: screen.deviceXDPI / screen.logicalXDPI (ou, pour le niveau de zoom par rapport à un zoom par défaut, screen.systemXDPI / screen.logicalXDPI)
  • IE7: var body = document.body,r = body.getBoundingClientRect(); return (r.left-r.right)/body.offsetWidth; (grâce à cet exemple ou cette réponse)
  • FF3.5 UNIQUEMENT: screen.width / media query largeur de l'écran (voir ci-dessous) (tire parti du fait que l' screen.width utilise l'appareil de pixels, mais MQ largeur utilise CSS pixels--merci à Quirksmode largeurs)
  • FF3.6: pas de méthode connue
  • FF4+: les requêtes de média binaire de recherche (voir ci-dessous)
  • WebKit: mesurer la taille d'un div avec -webkit-text-size-adjust:none.
  • WebKit: (en panne depuis r72591) document.width / jQuery(document).width() (merci à Dirk van Oosterbosch ci-dessus). Pour obtenir le ratio en termes de dispositif de pixels (au lieu de par rapport à un zoom par défaut), il faut multiplier par window.devicePixelRatio.
  • Vieux WebKit? (non vérifiées): parseInt(getComputedStyle(document.documentElement,null).width) / document.documentElement.clientWidth (à partir de cette réponse)
  • Opéra: document.documentElement.offsetWidth / largeur de la position:fixed; width:100% div. à partir d'ici (Quirksmode de largeurs de table dit que c'est un bug; innerWidth devrait être CSS px). Nous avons utiliser la position:élément fixe pour obtenir la largeur de la fenêtre d'affichage , y compris l'espace où les barres de défilement sont; document.documentElement.clientWidth exclut cette largeur. C'est en panne depuis quelque temps en 2011; je ne connais pas d'obtenir le niveau de zoom à l'Opéra plus.
  • Autres: Flash solution de Sebastian
  • Peu fiable: écouter les événements de la souris et de mesurer le changement dans les screenX / changement de clientX

Voici une version binaire de recherche pour Firefox 4, car je ne connais pas de variable à laquelle il est exposé:

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

50voto

user800583 Points 231

Merci pour cet excellent résumé.

Pour moi, pour Chrome/Webkit, document.largeur / jQuery(document).largeur() ne fonctionne pas. Quand j'ai fait ma fenêtre et le zoom sur mon site, tels que les barres de défilement horizontale est apparu, document.largeur / jQuery(document).largeur() n'est pas égale à 1 au niveau de zoom par défaut. C'est parce que le document.largeur inclut une partie du document à l'extérieur de la fenêtre d'affichage.

À l'aide de la fenêtre.innerWidth et de la fenêtre.outerWidth travaillé. Pour une raison quelconque dans Chrome, outerWidth est mesurée en pixels de l'écran et innerWidth est mesurée en pixels 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";
}

16voto

Jay Points 111

Ma collègue de travail et j'ai utilisé le script de https://github.com/tombigel/detect-zoom. En outre, nous avons également créé dynamiquement un élément svg et vérifier sa currentScale de la propriété. Il fonctionne très bien sur Chrome et probablement la plupart des navigateurs. Sur FF "zoom texte seulement" fonctionnalité doit être désactivée. SVG est pris en charge sur la plupart des navigateurs. Au moment d'écrire ces lignes, testé sur IE10, FF19 et 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);

12voto

brianh Points 51

J'ai trouvé cet article très utile. Un immense merci à yonran. Je voulais passer sur certains supplémentaire à l'apprentissage que j'ai trouvé lors de l'exécution de certaines des techniques qu'il a fourni. Dans FF6 et Chrome 9, le support pour les requêtes de média à partir de JS a été ajouté, qui permet de simplifier considérablement la requête de média approche nécessaire pour déterminer le zoom dans FF. Voir les docs au MDN ici. Pour ma part, j'ai seulement besoin de détecter si le navigateur a été un zoom avant ou arrière, je n'avais pas besoin pour le facteur de zoom. J'ai pu obtenir ma réponse avec une seule ligne de JavaScript:

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

La combinant avec la IE8+ Webkit et les solutions qui ont été aussi simple de lignes, j'ai été en mesure de détecter zoom sur la grande majorité des navigateurs qui frappe notre app avec seulement quelques lignes de code.

3voto

rudolfrck Points 19

Cela a fonctionné très bien pour moi dans les navigateurs basés sur webkit (Chrome, Safari) :

Ne semble pas fonctionner dans Firefox si.

Cela fonctionne aussi dans WebKit :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X