web-dev-qa-db-fra.com

Capturer l'événement "zoom" du navigateur en JavaScript

Est-il possible de détecter, en utilisant JavaScript, lorsque l'utilisateur modifie le zoom d'une page? Je veux simplement attraper un événement "zoom" et y répondre (semblable à l'événement window.onresize).

Merci.

149
user123093

Il n'y a aucun moyen de détecter activement s'il y a un zoom. J'ai trouvé une bonne entrée ici sur la façon dont vous pouvez essayer de l'implémenter.

J'ai trouvé deux moyens de détecter le niveau de zoom. Une façon de détecter les changements de niveau de zoom repose sur le fait que les valeurs en pourcentage ne sont pas zoomées. Une valeur en pourcentage est relative à la largeur de la fenêtre et n'est donc pas affectée par le zoom de page. Si vous insérez deux éléments, l’un avec une position en pourcentage et l’autre avec la même position en pixels, ils s’écartent lorsque la page est agrandie. Trouvez le rapport entre les positions des deux éléments et vous avez le niveau de zoom. Voir cas de test. http://web.archive.org/web/20080723161031/http://novemberborn.net/javascript/page-zoom-ff

Vous pouvez également le faire en utilisant les outils du post ci-dessus. Le problème est que vous faites plus ou moins des suppositions éclairées quant à savoir si la page a été zoomée ou non. Cela fonctionnera mieux dans certains navigateurs que d'autres.

Il n'y a aucun moyen de savoir si la page est zoomée si la page est chargée alors qu'elle est zoomée.

75
Ian Elliott

J'utilise cette partie de JavaScript pour réagir aux "événements" de Zoom.
Il interroge la largeur de la fenêtre. (Comme suggéré un peu sur cette page (à laquelle Ian Elliott s'est associé): http://novemberborn.net/javascript/page-zoom-ff[archive] )

Testé avec Chrome, Firefox 3.6 et Opera, pas IE.

Cordialement, Magnus

var zoomListeners = [];

(function(){
  // Poll the pixel width of the window; invoke zoom listeners
  // if the width has been changed.
  var lastWidth = 0;
  function pollZoomFireEvent() {
    var widthNow = jQuery(window).width();
    if (lastWidth == widthNow) return;
    lastWidth = widthNow;
    // Length changed, user must have zoomed, invoke listeners.
    for (i = zoomListeners.length - 1; i >= 0; --i) {
      zoomListeners[i]();
    }
  }
  setInterval(pollZoomFireEvent, 100);
})();
11
KajMagnus

Bonnes nouvelles toutes les personnes certaines personnes! Les nouveaux navigateurs déclenchent un événement de redimensionnement de la fenêtre lorsque le zoom est modifié.

11
Ben

Cela fonctionne pour moi:

        var deviceXDPI = screen.deviceXDPI;
        setInterval(function(){
            if(screen.deviceXDPI != deviceXDPI){
                deviceXDPI = screen.deviceXDPI;
                ... there was a resize ...
            }
        }, 500);

Ce n'est nécessaire que sur IE8. Tous les autres navigateurs génèrent naturellement un événement de redimensionnement.

7
Bill Keese

Il y a un plugin astucieux construit à partir de yonran qui peut faire la détection. Voici sa précédente réponse question sur StackOverflow. Cela fonctionne pour la plupart des navigateurs. L'application est aussi simple que cela:

window.onresize = function onresize() {
  var r = DetectZoom.ratios();
  zoomLevel.innerHTML =
    "Zoom level: " + r.zoom +
    (r.zoom !== r.devicePxPerCssPx
        ? "; device to CSS pixel ratio: " + r.devicePxPerCssPx
        : "");
}

démo

3
Starx

j'ai eu ce problème et finalement. J'ai une solution. c'est simple et fonctionne pour moi. ("Mozilla/5.0 (X11; Linux x86_64; Gecko/20100101 Firefox/50.0).

rapport px = rapport entre le pixel physique et le pixel px. si vous faites un zoom, les pixels de la fenêtre d’affichage sont réduits et doivent être adaptés à l’écran afin que le rapport devienne plus grand. mais dans le redimensionnement de la fenêtre, la taille de l’écran est réduite ainsi que celle des pixels. donc le ratio se maintiendra.

zoom: déclencher un événement windows.resize -> et changer le redimensionnement px_ratio: déclencher un événement windows.resize -> ne change pas px_ratio

//for zoom detection
px_ratio = window.devicePixelRatio || window.screen.availWidth / document.documentElement.clientWidth;

$(window).resize(function(){isZooming();});

function isZooming(){
    var newPx_ratio = window.devicePixelRatio || window.screen.availWidth / document.documentElement.clientWidth;
    if(newPx_ratio != px_ratio){
        px_ratio = newPx_ratio;
        console.log("zooming");
        return true;
    }else{
        console.log("just resizing");
        return false;
    }
}
3
abilogos

Sur iOS 10, il est possible d'ajouter un écouteur d'événement à l'événement touchmove et de détecter si la page est agrandie avec l'événement en cours.

var prevZoomFactorX;
var prevZoomFactorY;
element.addEventListener("touchmove", (ev) => {
  let zoomFactorX = document.documentElement.clientWidth / window.innerWidth;
  let zoomFactorY = document.documentElement.clientHeight / window.innerHeight;
  let pageHasZoom = !(zoomFactorX === 1 && zoomFactorY === 1);

  if(pageHasZoom) {
    // page is zoomed
    
    if(zoomFactorX !== prevZoomFactorX || zoomFactorY !== prevZoomFactorY) {
      // page is zoomed with this event
    }
  }
  prevZoomFactorX = zoomFactorX;
  prevZoomFactorY = zoomFactorY;
});
2
alwe

J'aimerais suggérer une amélioration par rapport à la solution précédente avec le suivi des modifications apportées à la largeur de la fenêtre. Au lieu de conserver votre propre groupe d'écouteurs d'événements, vous pouvez utiliser le système d'événements javascript existant et déclencher votre propre événement lors du changement de largeur et y lier des gestionnaires d'événements.

$(window).bind('myZoomEvent', function() { ... });

function pollZoomFireEvent() 
{ 

    if ( ... width changed ... ) {
        $(window).trigger('myZoomEvent');
    }
}

Throttle/debounce peut aider à réduire le taux d'appels de votre gestionnaire.

2
Alexey

Vous pouvez également obtenir les événements de redimensionnement du texte et le facteur de zoom en injectant une div contenant au moins un espace insécable (éventuellement caché) et en vérifiant régulièrement sa hauteur. Si la hauteur change, la taille du texte a changé (et vous savez combien - cela se déclenche également si la fenêtre est agrandie en mode pleine page et que vous obtiendrez toujours le facteur de zoom correct, avec la même hauteur/rapport de hauteur).

1
Argo
<script>
var zoomv = function() {
  if(topRightqs.style.width=='200px){
  alert ("zoom");
  }
};
zoomv();
</script>
1
SchoolforDesign

Bien que ce soit une question de 9 ans, le problème persiste!

J'ai détecté le redimensionnement tout en excluant le zoom dans un projet. J'ai donc modifié mon code pour le rendre capable de détecter à la fois le redimensionnement et le zoom exclusif. Cela fonctionne la plupart du temps, donc si la plupart est assez bon pour votre projet, alors cela devrait être utile! Il détecte le zoom 100% du temps dans ce que j'ai testé jusqu'à présent. Le seul problème est que si l'utilisateur devient fou (c.-à-d. En redimensionnant spastiquement la fenêtre) ou si la fenêtre est à la traîne, elle risque de se déclencher sous forme de zoom au lieu d'un redimensionnement de fenêtre.

Cela fonctionne en détectant un changement de window.outerWidth ou window.outerHeight comme fenêtre redimensionnant tout en détectant une modification de window.innerWidth ou window.innerHeight indépendant du redimensionnement de la fenêtre sous forme de zoom.

//init object to store window properties
var windowSize = {
  w: window.outerWidth,
  h: window.outerHeight,
  iw: window.innerWidth,
  ih: window.innerHeight
};

window.addEventListener("resize", function() {
  //if window resizes
  if (window.outerWidth !== windowSize.w || window.outerHeight !== windowSize.h) {
    windowSize.w = window.outerWidth; // update object with current window properties
    windowSize.h = window.outerHeight;
    windowSize.iw = window.innerWidth;
    windowSize.ih = window.innerHeight;
    console.log("you're resizing"); //output
  }
  //if the window doesn't resize but the content inside does by + or - 5%
  else if (window.innerWidth + window.innerWidth * .05 < windowSize.iw ||
    window.innerWidth - window.innerWidth * .05 > windowSize.iw) {
    console.log("you're zooming")
    windowSize.iw = window.innerWidth;
  }
}, false);

Remarque: ma solution ressemble à celle de KajMagnus, mais cela a mieux fonctionné pour moi.

1
dandeto