È possibile rilevare, utilizzando JavaScript, quando l'utente modifica lo zoom in una pagina? Voglio semplicemente catturare un evento "zoom" e rispondere ad esso (simile all'evento window.onresize).
Grazie.
È possibile rilevare, utilizzando JavaScript, quando l'utente modifica lo zoom in una pagina? Voglio semplicemente catturare un evento "zoom" e rispondere ad esso (simile all'evento window.onresize).
Grazie.
Risposte:
Non c'è modo di rilevare attivamente se c'è uno zoom. Ho trovato una buona voce qui su come puoi tentare di implementarlo.
Ho trovato due modi per rilevare il livello di zoom. Un modo per rilevare le variazioni del livello di zoom si basa sul fatto che i valori percentuali non vengono ingranditi. Un valore percentuale è relativo alla larghezza della finestra e quindi non è influenzato dallo zoom della pagina. Se inserisci due elementi, uno con una posizione in percentuale e uno con la stessa posizione in pixel, si sposteranno quando viene ingrandita la pagina. Trova il rapporto tra le posizioni di entrambi gli elementi e hai il livello di zoom. Vedi test case. http://web.archive.org/web/20080723161031/http://novemberborn.net/javascript/page-zoom-ff3
Puoi anche farlo usando gli strumenti del post sopra. Il problema è che stai più o meno facendo ipotesi ponderate sull'eventuale zoom della pagina. Funzionerà meglio in alcuni browser rispetto ad altri.
Non c'è modo di sapere se la pagina viene ingrandita se caricano la pagina durante lo zoom.
document.body.offsetWidth
Sto usando questo pezzo di JavaScript per reagire agli "eventi" di Zoom.
Esegue il polling della larghezza della finestra. (Come suggerito in qualche modo in questa pagina (a cui Ian Elliott si collegava): http://novemberborn.net/javascript/page-zoom-ff3 [archivio] )
Testato con Chrome, Firefox 3.6 e Opera, non IE.
Saluti, 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);
})();
Buone notizie tuttialcune persone! I browser più recenti attiveranno un evento di ridimensionamento della finestra quando si modifica lo zoom.
Definiamo px_ratio come di seguito:
Rapporto px = rapporto tra pixel fisici e px pixel.
se uno qualsiasi ingrandisce la Pagina, il pxes del viewport (px è diverso dal pixel) si riduce e dovrebbe adattarsi allo schermo, quindi il rapporto (pixel fisico / CSS_px) deve aumentare.
ma nella finestra Ridimensionamento, la dimensione dello schermo si riduce così come i px. quindi il rapporto manterrà.
ma
ridimensionamento: attiva l'evento windows.resize -> non cambia 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;
}
}
Il punto chiave è la differenza tra CSS PX e Physical Pixel.
https://gist.github.com/abilogos/66aba96bb0fb27ab3ed4a13245817d1e
Questo funziona per me:
var deviceXDPI = screen.deviceXDPI;
setInterval(function(){
if(screen.deviceXDPI != deviceXDPI){
deviceXDPI = screen.deviceXDPI;
... there was a resize ...
}
}, 500);
È necessario solo su IE8. Tutti gli altri browser generano naturalmente un evento di ridimensionamento.
È stato creato un plug-in elegante yonran
che può fare il rilevamento. Ecco la sua domanda precedentemente risposta su StackOverflow. Funziona per la maggior parte dei browser. L'applicazione è semplice come questa:
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
: "");
}
Always enable zoom
pulsante nell'opzione Accessibilità. La demo non reagirà al cambiamento.
Vorrei suggerire un miglioramento alla soluzione precedente con il rilevamento delle modifiche alla larghezza della finestra. Invece di mantenere il proprio array di listener di eventi, è possibile utilizzare il sistema di eventi javascript esistente e attivare il proprio evento in caso di modifica della larghezza e associare i gestori di eventi ad esso.
$(window).bind('myZoomEvent', function() { ... });
function pollZoomFireEvent()
{
if ( ... width changed ... ) {
$(window).trigger('myZoomEvent');
}
}
Acceleratore / rimbalzo può aiutare a ridurre la frequenza delle chiamate del gestore.
Puoi anche ottenere gli eventi di ridimensionamento del testo e il fattore di zoom iniettando un div contenente almeno uno spazio non interrompibile (possibilmente, nascosto) e controllando regolarmente la sua altezza. Se l'altezza cambia, la dimensione del testo è cambiata, (e sai quanto - anche questo si attiva, per inciso, se la finestra viene ingrandita in modalità pagina intera e otterrai comunque il fattore di zoom corretto, con la stessa altezza / rapporto di altezza).
<script>
var zoomv = function() {
if(topRightqs.style.width=='200px){
alert ("zoom");
}
};
zoomv();
</script>
Su iOS 10 è possibile aggiungere un listener di touchmove
eventi all'evento e rilevare se la pagina viene ingrandita con l'evento corrente.
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;
});
Anche se questa è una domanda di 9 anni, il problema persiste!
Ho rilevato il ridimensionamento escludendo lo zoom in un progetto, quindi ho modificato il mio codice per farlo funzionare per rilevare sia il ridimensionamento che lo zoom in modo esclusivo l'uno dall'altro. Funziona la maggior parte delle volte, quindi se la maggior parte è abbastanza buona per il tuo progetto, questo dovrebbe essere utile! Rileva lo zoom il 100% delle volte in ciò che ho testato finora. L'unico problema è che se l'utente impazzisce (ad es. Ridimensionando spasticamente la finestra) o se la finestra è in ritardo, potrebbe attivarsi come uno zoom anziché un ridimensionamento della finestra.
Funziona rilevando una modifica window.outerWidth
o window.outerHeight
come ridimensionamento della finestra mentre rileva una modifica window.innerWidth
o window.innerHeight
indipendente dal ridimensionamento della finestra come 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);
Nota: la mia soluzione è come quella di KajMagnus, ma per me ha funzionato meglio.
0.05
senza almeno fornire una buona spiegazione. ;-) Ad esempio, so che in Chrome, in particolare, il 10% è la quantità minima che il browser eseguirà lo zoom in ogni caso, ma non è chiaro che questo sia vero per altri browser. a proposito, assicurati sempre che il tuo codice sia testato e preparati a difenderlo o migliorarlo.
Ecco una soluzione pulita:
// polyfill window.devicePixelRatio for IE
if(!window.devicePixelRatio){
Object.defineProperty(window,'devicePixelRatio',{
enumerable: true,
configurable: true,
get:function(){
return screen.deviceXDPI/screen.logicalXDPI;
}
});
}
var oldValue=window.devicePixelRatio;
window.addEventListener('resize',function(e){
var newValue=window.devicePixelRatio;
if(newValue!==oldValue){
// TODO polyfill CustomEvent for IE
var event=new CustomEvent('devicepixelratiochange');
event.oldValue=oldValue;
event.newValue=newValue;
oldValue=newValue;
window.dispatchEvent(event);
}
});
window.addEventListener('devicepixelratiochange',function(e){
console.log('devicePixelRatio changed from '+e.oldValue+' to '+e.newValue);
});
L'evento di ridimensionamento funziona sui browser moderni collegando l'evento window
e quindi leggendo i valori body
dell'elemento, o altro, ad esempio ( .getBoundingClientRect () ).
In alcuni browser precedenti era possibile registrare i gestori di eventi di ridimensionamento su qualsiasi elemento HTML. È ancora possibile impostare attributi onresize o utilizzare addEventListener () per impostare un gestore su qualsiasi elemento. Tuttavia, gli eventi di ridimensionamento vengono generati solo sull'oggetto window (ovvero restituito da document.defaultView). Solo i gestori registrati sull'oggetto window riceveranno eventi di ridimensionamento .
window.addEventListener("resize", getSizes, false)
function getSizes(){
let body = document.body
console.log(body.clientWidth +"px x "+ body.clientHeight + "px")
}
Un'altra alternativa : l'API ResizeObserver
A seconda del layout, puoi guardare per ridimensionare un elemento particolare.
Funziona bene su layout «reattivi», perché il riquadro contenitore viene ridimensionato durante lo zoom.
function watchBoxchange(e){
// console.log(e[0].contentBoxSize.inlineSize+" "+e[0].contentBoxSize.blockSize)
info.textContent = e[0].contentBoxSize.inlineSize+" * "+e[0].contentBoxSize.blockSize + "px"
}
new ResizeObserver(watchBoxchange).observe(fluid)
#fluid {
width: 200px;
height:100px;
overflow: auto;
resize: both;
border: 3px black solid;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 8vh
}
<div id="fluid">
<info id="info"></info>
</div>
Fare attenzione a non sovraccaricare le attività javascript dagli eventi dei gesti degli utenti. Utilizzare requestAnimationFrame ogni volta che è necessario ridisegnare.
Secondo MDN, "matchMedia" è il modo corretto di farlo https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#Monitoring_screen_resolution_or_zoom_level_changes
è un po 'pignolo perché ogni istanza può guardare solo un MQ alla volta, quindi se sei interessato a qualsiasi modifica del livello di zoom devi fare un sacco di abbinamenti .. ma poiché il browser è responsabile dell'emissione degli eventi è probabilmente ancora più performante del polling e potresti rallentare o rimbalzare il callback o appuntarlo a un frame di animazione o qualcosa del genere - ecco un'implementazione che sembra piuttosto scattante, sentiti libero di scambiare in _throttle o qualunque altra cosa se sei già dipendente da quello.
Esegui lo snippet di codice e ingrandisci e rimpicciolisci nel tuo browser, osserva il valore aggiornato nel markup: l'ho provato solo su Firefox! fammi sapere se riscontri problemi.
const el = document.querySelector('#dppx')
if ('matchMedia' in window) {
function observeZoom(cb, opts) {
opts = {
// first pass for defaults - range and granularity to capture all the zoom levels in desktop firefox
ceiling: 3,
floor: 0.3,
granularity: 0.05,
...opts
}
const precision = `${opts.granularity}`.split('.')[1].length
let val = opts.floor
const vals = []
while (val <= opts.ceiling) {
vals.push(val)
val = parseFloat((val + opts.granularity).toFixed(precision))
}
// construct a number of mediamatchers and assign CB to all of them
const mqls = vals.map(v => matchMedia(`(min-resolution: ${v}dppx)`))
// poor person's throttle
const throttle = 3
let last = performance.now()
mqls.forEach(mql => mql.addListener(function() {
console.debug(this, arguments)
const now = performance.now()
if (now - last > throttle) {
cb()
last = now
}
}))
}
observeZoom(function() {
el.innerText = window.devicePixelRatio
})
} else {
el.innerText = 'unable to observe zoom level changes, matchMedia is not supported'
}
<div id='dppx'>--</div>
Sto rispondendo a un link di 3 anni, ma immagino che qui sia una risposta più accettabile,
Crea il file .css come,
@media screen and (max-width: 1000px)
{
// things you want to trigger when the screen is zoomed
}
PER ESEMPIO:-
@media screen and (max-width: 1000px)
{
.classname
{
font-size:10px;
}
}
Il codice sopra riportato rende la dimensione del carattere '10px' quando lo schermo viene ingrandito a circa il 125%. Puoi controllare diversi livelli di zoom cambiando il valore di '1000px'.
max-width
rapporto di zoom e?