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

310
  1. Comment puis-je détecter le niveau de zoom de la page dans tous les navigateurs modernes? Bien que ce fil explique comment le faire dans IE7 et IE8, je ne trouve pas de bonne solution multi-navigateur.

  2. Firefox stocke le niveau de zoom de la page pour un accès futur. Lors du premier chargement de page, pourrais-je obtenir le niveau de zoom? Quelque part, j'ai lu que cela fonctionne lorsqu'un changement de zoom se produit après le chargement de la page.

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

J'en ai besoin car certains de mes calculs sont basés sur des pixels et peuvent fluctuer lors d'un zoom.


Échantillon modifié donné par @tfl

Cette page alerte différentes valeurs de hauteur lors d'un 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>
comprendre
la source
1
Fondamentalement, je veux connaître la dimension d'un DIV à 100% de zoom.
sous-
4
Fondamentalement, il n'y a aucun moyen de détecter le zoom en 2019 : j'ai testé toutes les solutions ci-dessous sur Chrome 78 sur Mac Catalina et aucune d'entre elles n'a fonctionné.
collimarco

Réponses:

274

Maintenant, c'est un gâchis encore plus grand qu'il ne l'était lorsque cette question a été posée pour la première fois. En lisant toutes les réponses et les articles 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 .

Éditer (12/12/2011): 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 au 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 largeur d'écran de la requête / media (voir ci-dessous) (tire parti du fait qu'il screen.widthutilise des pixels de l'appareil mais que la largeur MQ utilise des pixels CSS - grâce aux largeurs Quirksmode )
  • FF3.6 : pas de méthode connue
  • FF4 + : recherche binaire des requêtes média (voir ci-dessous)
  • WebKit : https://www.chromestatus.com/feature/5737866978131968 (merci à Teo dans les commentaires)
  • WebKit : mesurez la taille préférée d'un div avec -webkit-text-size-adjust:none.
  • WebKit : (cassé depuis r72591 ) document.width / jQuery(document).width()(merci à Dirk van Oosterbosch ci-dessus ). Pour obtenir le ratio en termes de pixels de l'appareil (au lieu de par rapport au zoom par défaut), multipliez par window.devicePixelRatio.
  • Vieux WebKit? (non vérifié): parseInt(getComputedStyle(document.documentElement,null).width) / document.documentElement.clientWidth(à partir de cette réponse )
  • Opéra : document.documentElement.offsetWidth/ largeur d'une position:fixed; width:100%div. d'ici ( le tableau des largeurs de Quirksmode indique que c'est un bogue; innerWidth devrait être CSS px). Nous utilisons l'élément position: fixed pour obtenir la largeur de la fenêtre, y compris l'espace où se trouvent les barres de défilement ; document.documentElement.clientWidth exclut cette largeur. Cela est cassé depuis quelque temps en 2011; Je ne sais plus comment obtenir le niveau de zoom dans Opera.
  • Autre : Solution Flash de Sebastian
  • Peu fiable: écoutez les événements de la souris et mesurez le changement dans screenX / changement dans clientX

Voici une recherche binaire pour Firefox 4, car je ne connais aucune variable où 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>
yonran
la source
1
Très beau travail, bien que cela ne fonctionne pas pour moi dans IE 8.0.7601.17514 (dernière). Avez-vous une chance de conclure tout cela dans une seule fonction getZoom () qui fonctionne sur tous les navigateurs? Peut-être aussi publier en tant que plugin jQuery? Beau travail à nouveau.
ripper234
1
@yonran great plugin !, Mais cela ne fonctionne pas dans IE9, il devrait l'être à la zoom: screen.deviceXDPI / screen.logicalXDPI,place dezoom: screen.systemXDPI / screen.logicalXDPI,
Daniel
1
@RobW, lorsque j'ai écrit ceci pour Firefox 4, Firefox n'en avait pas matchMedia. Paul Irish a également écrit un polyfill matchMedia similaire qui fait partie de Modernizr .
yonran
7
Bonnes nouvelles tout le monde! Ils l'ont finalement fait! API Vieport! chromestatus.com/feature/5737866978131968 Je le teste, super truc!
Teo
3
L'API Viewport ne fonctionne que pour le zoom par pincement; si vous zoomez sur le bureau, il est dit que l'échelle est de 1. @ Jason T Featheringham, il y a des raisons autres que la "discrimination" pour vouloir connaître le niveau de zoom. Le zoom est défini sur toutes les pages d'un domaine, mais vous voudrez peut-être le gérer différemment dans une page de jeu ou une fenêtre d'extension que dans une page d'aide.
Pudica
61

Tu peux essayer

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

Cela vous donnera le niveau de pourcentage de zoom du navigateur sur les écrans non rétiniens. Pour les écrans à haute résolution / rétine, cela donnerait des valeurs différentes (par exemple, 200 pour Chrome et Safari, 140 pour Firefox).

Pour capturer un événement de zoom, vous pouvez utiliser

$(window).resize(function() { 
// your code 
});
user1080381
la source
1
Fonctionne parfaitement, également sur les appareils mobiles. Il est également très intéressant de voir quels appareils mobiles ont quoi devicePixelRatio. Cela m'a aussi beaucoup aidé à changer un fixedélément en élément absolutepositionné ly lorsque l'événement de zoom se produit ou lorsque la valeur initiale des devicePixelRatiochangements. Parfait! Je vous remercie!!
lowtechsun
12
Ne fonctionne pas comme prévu: il renvoie 200 dans Chrome sur MacBook avec rétine lorsque le navigateur n'est pas zoomé.
Terite
19
Les navigateurs prenant en charge les écrans à haute résolution ne donneront pas le résultat escompté lors de l'utilisation d'un tel affichage, pas plus que Safari, quel que soit l'affichage.
Fredrik C
Pour tous ceux qui s'en soucient, sur IE, cela ne fonctionne que sur IE11 (il retournera NaN sur IE10 ou ci-dessous)
scunliffe
3
Math.round(window.devicePixelRatio * 100)fonctionne sur Chrome, IE, Edge et Firefox. Safari sur iMac renvoie toujours 200.
Super Jade
45

Pour moi, pour Chrome / Webkit, cela document.width / jQuery(document).width()n'a pas fonctionné. Quand j'ai fait ma petite fenêtre et zoomé sur mon site de telle sorte que des barres de défilement horizontales apparaissent,document.width / jQuery(document).width() n'était pas égal à 1 au zoom par défaut. En effet, document.widthinclut une partie du document en dehors de la fenêtre.

Utilisation window.innerWidthet window.outerWidthtravail. Pour une raison quelconque dans Chrome, la largeur extérieure est mesurée en pixels d'écran et la largeur intérieure 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";
}
user800583
la source
1
Très agréable. Et si vous avez seulement besoin de savoir si c'est zoomé ou non dans Chrome:isZoomed = (screenCssPixelRatio < .98 || screenCssPixelRatio > 1.02)
Brent Faust
1
Eh bien, window.outerWidth est également modifié avec le zoom. De plus, pas sur tous les systèmes d'exploitation, la largeur de la bordure de la fenêtre est de 8 pixels (même sur le même système d'exploitation, la conception peut varier). Cependant, je suggère de soustraire 16, pas 8, car vous avez les bordures de fenêtre deux fois. De plus, certains navigateurs ont une bordure sur leur fenêtre de rendu réelle (comme FF) et d'autres pas (Safari) - mais même cela dépend de l'OS que vous utilisez le navigateur (par exemple, Safari a une bordure sur Windows). Sauvegarder la largeur intérieure initiale (par exemple au chargement de la page) et l'utiliser pour comparer fonctionne mieux mais seulement si le zoom initial était à 100% ...
StanE
1
Sorties 0 peu importe pour moi (2017, fév).
Tiberiu-Ionuț Stan
1
switchpeut être meilleure que beaucoup d'instructions if else.
Edric
Cela ne fonctionne pas: juste testé sur Chrome sur Mac et il retourne toujours le même rapport, quel que soit le niveau de zoom
collimarco
16

Mon collègue et moi avons utilisé le script de https://github.com/tombigel/detect-zoom . De plus, nous avons également créé dynamiquement un élément svg et vérifié sa propriété currentScale. Cela fonctionne très bien sur Chrome et probablement sur la plupart des navigateurs. Sur FF, la fonction "zoom texte uniquement" doit être désactivée. SVG est pris en charge sur la plupart des navigateurs. Au moment de la rédaction de ce document, 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);
Geai
la source
Cette méthode rapporte désormais toujours svg.currentScale = 1 dans Firefox 29. Probablement parce qu'ils redimensionnent la totalité des figures de l'écran en fonction du zoom, ce qui est un bug . IE11 semble avoir le même problème sur le bureau avec la hauteur de l'écran ajustée au périphérique de visualisation PixelRatio qui est assez foiré.
hexalys
11

J'ai trouvé cet article extrêmement utile. Un grand merci à yonran. Je voulais transmettre un apprentissage supplémentaire que j'ai trouvé lors de la mise en œuvre de certaines des techniques qu'il a fournies. Dans FF6 et Chrome 9, la prise en charge des requêtes multimédias de JS a été ajoutée, ce qui peut grandement simplifier l'approche de requête multimédia nécessaire pour déterminer le zoom dans FF. Voir les documents sur MDN ici . Pour mes besoins, j'avais seulement besoin de détecter si le navigateur était zoomé ou dézoomé, je n'avais pas besoin du facteur de zoom réel. 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;

En combinant cela avec les solutions IE8 + et Webkit, qui étaient également des lignes simples, j'ai pu détecter un zoom sur la grande majorité des navigateurs qui frappaient notre application avec seulement quelques lignes de code.

brianh
la source
4
Pourriez-vous s'il vous plaît fournir un code pour détecter le zoom réel à l'aide de la requête multimédia?
TN.
Essayez d'utiliser uniquement "(largeur: <X> px) et (hauteur: <Y> px)" où <X> et <Y> sont window.innerWidth et window.innerHeight, respectivement. Cela fonctionne même pour de très petites quantités de zoom. Fonctionne également dans Safari.
max
@max Pouvez-vous fournir un JSFIddle ou un exemple de code sur la façon dont cela se présente, s'il vous plaît?
lowtechsun
Signale toujours vrai sur les appareils Retina tels que MacBook Pro.
Matthew Sanders
codepen.io/anon/pen/LgrGjJ montre une recherche binaire avec des requêtes multimédias, mais c'est la même chose que la requête devicePixelRatio: elle prend en compte la mise à l'échelle de l'affichage.
ZachB
11
zoom = ( window.outerWidth - 10 ) / window.innerWidth

C'est tout ce dont vous avez besoin.

Alex von Thorn
la source
Pourquoi soustraire 10de outerWidth?
callum
Probablement pour la barre de défilement. Chaque barre de défilement est également différente, comme dans iOS, elle est beaucoup plus petite. De plus, cette solution ne semble être que du chrome
Sarah
1
Cela ne fonctionne pas si l'utilisateur a une barre latérale telle que des signets dans FF
Gerrit Sedlaczek
7

J'ai une solution pour cela depuis janvier 2016. Testé fonctionnant dans les navigateurs Chrome, Firefox et MS Edge.

Le principe est le suivant. Collectez 2 points MouseEvent éloignés l'un de l'autre. Chaque événement de souris est accompagné des coordonnées de l'écran et du document. Mesurez la distance entre les 2 points dans les deux systèmes de coordonnées. Bien qu'il existe des décalages fixes variables entre les systèmes de coordonnées en raison du mobilier du navigateur, la distance entre les points doit être identique si la page n'est pas agrandie. La raison de la spécification de «éloigné» (je mets 12 pixels) est pour que de petits changements de zoom (par exemple 90% ou 110%) soient détectables.

Référence: https://developer.mozilla.org/en/docs/Web/Events/mousemove

Pas:

  1. Ajouter un écouteur de déplacement de souris

    window.addEventListener("mousemove", function(event) {
        // handle event
    });
  2. Capturez 4 mesures d'événements de souris:

    event.clientX, event.clientY, event.screenX, event.screenY
  3. Mesurer la distance d_c entre les 2 points du système client

  4. Mesurer la distance d_s entre les 2 points du système d'écran

  5. Si d_c! = D_s alors le zoom est appliqué. La différence entre les deux vous indique le niveau de zoom.

NB Ne faites que rarement les calculs de distance, par exemple lorsque vous pouvez échantillonner un nouvel événement de souris loin du précédent.

Limitations: suppose que l'utilisateur déplace la souris au moins un peu et que le zoom est inconnu jusqu'à ce moment.

user1191311
la source
1
J'ai créé un violon: jsfiddle.net/Terite/9b6ko854 avec "éloigné" de 100 pixels. Malheureusement, il fonctionne de manière instable sur Firefox (52) sur MacBook avec écran Retina. Il convient également de noter que le zoom de l'interface de Windows 7 125% est détecté dans Chrome, Firefox et IE11 (dans le zoom 125% qui est par défaut alors) en tant que zoom du navigateur.
Terite
Votre violon fonctionne pour moi, testé sous Linux avec Firefox et Chrome :)
user1191311
Les écrans Retina ajoutent un autre niveau de difficulté car ils signalent de manière incorrecte la taille des pixels, entre autres.
user1191311
5

Vous pouvez utiliser l' API Visual Viewport :

window.visualViewport.scale;

Il est standard et fonctionne à la fois sur ordinateur et sur mobile: prise en charge du navigateur .

collimarco
la source
Cela semble pratique, mais il est toujours désactivé par défaut dans le bureau Firefox et ne fonctionne pas dans Internet Explorer au 31/05/20.
derekbaker783
3

Dans Internet Explorer 7, 8 et 9, cela fonctionne:

function getZoom() {
    var screen;

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

Le "+0,9" est ajouté pour éviter les erreurs d'arrondi (sinon, vous obtiendriez 104% et 109% lorsque le zoom du navigateur est réglé sur 105% et 110% respectivement).

Dans IE6, le zoom n'existe pas, il n'est donc pas nécessaire de vérifier le zoom.

pench
la source
1
Intéressant. Pour moi, il affiche toujours 80% du zoom ... Je pense que c'est parce que j'ai de grandes polices configurées au niveau de Windows 7 (recherchez "taille de police" dans le panneau de configuration). C'est mieux que la solution IE8 dans la réponse de @ yonran qui ne fonctionnait pas du tout pour moi. jsbin.com/obowof
ripper234
J'obtiens 101% lorsque le zoom est réglé sur 100%.
Allen Wallace
moi aussi. utilisez 0.4999 au lieu de 0.9
yan bellavance
ieZoomLevel = ((screen.deviceXDPI / screen.systemXDPI) * 100 + 0.4999) .toFixed ();
yan bellavance du
3

Ce que j'ai trouvé c'est:

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

2) lorsque la page se charge:

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

Et cela a fonctionné pour moi ctrl+et les ctrl-zooms.

ou je peux ajouter la ligne à un $(window).onresize()événement pour obtenir le niveau de zoom actif


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>

PS: c'est mon premier post, pardonnez les erreurs

Abhishek Borar
la source
3
Malheureusement, cela ne fonctionnera que si l'utilisateur a maximisé le navigateur ( screen.availWidthindique la largeur de l'écran en pixels d'écran, pas la fenêtre du navigateur).
Bailey Parker
3

Cela a très bien fonctionné pour moi dans les navigateurs 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;
}

Cela ne semble cependant pas fonctionner dans Firefox.

Cela fonctionne également dans WebKit:

var zoomLevel = document.width / document.body.clientWidth;
rudolfrck
la source
5
document.widthrenvoie indéfini
Adam
Retourne toujours vrai quel que soit le zoom (2017, février, affichage de la rétine).
Tiberiu-Ionuț Stan
3

Fondamentalement, nous avons:

  • window.devicePixelRatio qui prend en compte à la fois le zoom au niveau du navigateur * ainsi que le zoom du système / la densité de pixels.
    * - sur Mac / Safari le niveau de zoom n'est pas pris en compte
  • requêtes médias
  • vw/vh Unités CSS
  • resize , qui est déclenché lors d'un changement de niveau de zoom, entraîne une modification de la taille effective de la fenêtre

cela devrait être suffisant pour la normale UX . Si vous devez détecter le niveau de zoom, cela pourrait être un signe de mauvaise conception de l'interface utilisateur.

Le zoom en hauteur est plus difficile à suivre et n'est pas pris en compte actuellement.

kirilloïde
la source
1
window.devicePixelRatio est une bonne réponse qui fonctionne dans la dernière version des principaux navigateurs - Chrome, Safari, FF, Edge, IE
DShultz
@kirilloid avez-vous trouvé quelque chose qui pourrait être utilisé pour trouver de manière fiable le "niveau de zoom" dans Safari?
onassar
1

Vos calculs sont toujours basés sur un certain nombre de pixels CSS. Ils sont juste d'une taille différente à l'écran maintenant. C'est le point du zoom pleine page.

Que voudriez-vous qu'il se passe sur un navigateur sur un périphérique 192 dpi qui affiche donc normalement quatre pixels de périphérique pour chaque pixel d'une image? Avec un zoom de 50%, cet appareil affiche désormais un pixel d'image dans un pixel d'appareil.

Neil
la source
@Neil: comment obtenir les dimensions des "pixels CSS"?
sous-
CSS utilise par défaut des points, mais vous pouvez bien sûr spécifier des pixels en utilisant le modificateur de dimension px. Quant aux propriétés des éléments récupérées en JavaScript, elles devraient déjà être en pixels CSS. Donc, si vous spécifiez la largeur d'un <div> à 100px, c'est ce que vous obtiendrez de JavaScript, quel que soit le niveau de zoom.
Neil
1

Sur Chrome

var ratio = (screen.availWidth / document.documentElement.clientWidth);
var zoomLevel = Number(ratio.toFixed(1).replace(".", "") + "0");
Nicolas Giszpenc
la source
1
Fonctionne uniquement lorsque la fenêtre du navigateur a toute la largeur de l'écran.
tenbits
0

Je n'ai pas testé cela pour IE, mais si vous créez un élément elemavec

min-width: 100%

puis

window.document.width / elem.clientWidth

vous donnera le niveau de zoom de votre navigateur (y compris le document.body.style.zoomfacteur).

Dirk van Oosterbosch
la source
Testé mais le zoom avant ne semble pas augmenter elem.clientWidth
Tom
0

C'est pour Chrome , dans le sillage de la réponse de l'utilisateur 800583 ...

J'ai passé quelques heures sur ce problème et n'ai pas trouvé de meilleure approche, mais:

  • Il y a 16 'zoomLevel' et pas 10
  • Lorsque Chrome est en plein écran / maximisé, le ratio est window.outerWidth/window.innerWidth, et quand il ne l'est pas, le ratio semble être (window.outerWidth-16)/window.innerWidth, cependant le 1er cas peut être approché par le 2ème.

Je suis donc arrivé à ce qui suit ...

Mais cette approche a ses limites: par exemple, si vous jouez de l'accordéon avec la fenêtre de l'application (agrandissez et réduisez rapidement la largeur de la fenêtre), vous obtiendrez des écarts entre les niveaux de zoom bien que le zoom n'ait pas changé (peut être la largeur externe et la largeur intérieure ne sont pas exactement mis à jour en même temps).

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

Et si vous voulez le facteur:

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 ]
);
jeum
la source
J'ai eu des problèmes avec "window.outerWidth / window.innerWidth" en me donnant la mauvaise valeur aussi et cela pourrait être dû au fait que j'étais dans un iframe. Donc, ce que j'ai fait, c'est que j'ai utilisé la fenêtre parent et elle a donné la bonne réponse: window.parent.window.outerWidth / window.parent.window.innerWidth
yan bellavance
0

J'ai cette solution pour mobile uniquement (testée avec 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());

});

Si vous voulez le niveau de zoom juste après le mouvement de pincement, vous devrez probablement définir un petit délai en raison du retard de rendu (mais je ne suis pas sûr car je ne l'ai pas testé).

pmrotule
la source
0

Cette réponse est basée sur des commentaires sur devicePixelRatio revenant incorrectement sur la réponse de user1080381.

J'ai constaté que cette commande revenait incorrectement dans certains cas également lorsque je travaillais avec un bureau, Surface Pro 3 et Surface Pro 4.

Ce que j'ai trouvé, c'est que cela fonctionnait sur mon bureau, mais le SP3 et le SP4 donnaient des numéros différents les uns des autres et du bureau.

J'ai cependant remarqué que le SP3 revenait à 1 fois et demie le niveau de zoom que j'attendais. Quand j'ai regardé les paramètres d'affichage, le SP3 était en fait réglé à 150% au lieu des 100% que j'avais sur mon bureau.

Ainsi, la solution aux commentaires devrait être de diviser le niveau de zoom renvoyé par l'échelle de la machine sur laquelle vous vous trouvez actuellement.

J'ai pu obtenir l'échelle dans les paramètres Windows en procédant comme suit:

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

Donc, dans le cas de mon SP3, voici à quoi ressemble ce code à 100% de zoom:

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

La multiplication par 100 dans la réponse originale de user1080381 vous donnerait alors un zoom de 100 (%).

Cameron Weaver
la source
0

Le faire fonctionner mais doit encore être séparé par navigateur. Testé avec succès sur Chrome (75) et Safari (11.1) (pas encore trouvé de chemin pour FF). Il obtient également la valeur de zoom correcte sur l'affichage de la rétine et les calculs sont déclenchés lors de l'événement de redimensionnement.

    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()
    };
  }
Yogi
la source
-1

ici ça ne change pas!:

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

créer un simple fichier html, cliquez sur le bouton. quel que soit le niveau de zoom: il vous montrera la largeur de 400px (au moins avec firefox et ie8)


la source
@tfl: c'est parce que vous avez fixé la largeur dans un style en ligne. J'ai modifié votre échantillon pour montrer mon cas (publié dans la question d'origine).
sous-
-1

Cela peut ou peut ne pas aider personne, mais j'avais une page que je n'arrivais pas à centrer correctement, peu importe les astuces Css que j'ai essayées, j'ai donc écrit une page de centre d'appels de fichier JQuery:

Le problème s'est produit avec le niveau de zoom du navigateur, la page se décalerait selon que vous étiez à 100%, 125%, 150%, etc.

Le code ci-dessous se trouve dans un fichier JQuery appelé centerpage.js.

Depuis ma page, j'ai dû créer un lien vers JQuery et ce fichier pour le faire fonctionner, même si ma page maître avait déjà un lien vers 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();
});

De plus, si vous souhaitez centrer un panneau:

// 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);
    }
}
user1054326
la source
-1

Cette question a été publiée il y a longtemps, mais aujourd'hui, lorsque je cherchais la même réponse "Comment détecter un événement de zoom avant et arrière", je n'ai pas pu trouver une réponse qui conviendrait à tous les navigateurs.

Comme maintenant: pour Firefox / Chrome / IE8 et IE9, le zoom avant et arrière déclenche un événement window.resize. Cela peut être capturé en utilisant:

$(window).resize(function() {
//YOUR CODE.
});
Bhumi Singhal
la source
-1

Solution de contournement pour FireFox 16+ pour trouver DPPX (niveau de zoom) uniquement avec 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);
lexass
la source
Cela ne fonctionne pas comme prévu dans Firefox (52) sur MacBook avec écran Retina - renvoie 2 lorsqu'il n'est pas en zoom. J'ai créé un violon: 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;
};
Ali
la source
6
Veuillez également expliquer comment fonctionne votre code. Cela sera utile si un novice trouve votre réponse.
displayName
J'ai créé un violon: jsfiddle.net/Terite/5n1bk9do As @AlexeySh. mentionné, cela ne fonctionne pas comme prévu sur l'affichage de la rétine dans Chrome (56), Firefox (52). Il affiche également 0 en zoom sur Safari (10).
Terite
-1

Le problème réside dans les types de moniteur utilisés, un moniteur 4k contre un moniteur standard. Chrome est de loin le plus intelligent pour pouvoir nous dire quel est le niveau de zoom simplement en utilisant window.devicePixelRatio, apparemment il peut dire quelle est la densité de pixels et rapporte le même nombre pour n'importe quoi.

D'autres navigateurs, pas tellement. IE et Edge sont probablement les pires, car ils gèrent les niveaux de zoom très différemment. Pour obtenir la même taille de texte sur un moniteur 4k, vous devez sélectionner 200%, au lieu de 100% sur un moniteur standard.

Depuis mai 2018, voici ce que j'ai pour détecter les niveaux de zoom pour certains des navigateurs les plus populaires, Chrome, Firefox et IE11. Je dois me dire quel est le pourcentage de zoom. Pour IE, il rapporte 100% même pour les moniteurs 4k qui sont en fait à 200%, mais la taille du texte est vraiment la même.

Voici un violon: https://jsfiddle.net/ae1hdogr/

Si quelqu'un souhaite essayer d'autres navigateurs et mettre à jour le violon, alors faites-le. Mon objectif principal était de couvrir ces 3 navigateurs pour détecter si les gens utilisaient un facteur de zoom supérieur à 100% pour utiliser mon application Web et afficher un avis suggérant un facteur de zoom du bailleur.

Bill_VA
la source
Safari sur Mac Book Pro (écran rétine) renvoie 0, Chrome sur l'écran non rétine renvoie correctement, il semble 100, 90, etc.
OZZIE
Renvoie 200 sur l'écran Retina de Chrome et Firefox
OZZIE