Ist es möglich, mithilfe von JavaScript zu erkennen, wann der Benutzer den Zoom einer Seite ändert? Ich möchte einfach ein "Zoom" -Ereignis abfangen und darauf reagieren (ähnlich wie bei window.onresize).
Vielen Dank.
Ist es möglich, mithilfe von JavaScript zu erkennen, wann der Benutzer den Zoom einer Seite ändert? Ich möchte einfach ein "Zoom" -Ereignis abfangen und darauf reagieren (ähnlich wie bei window.onresize).
Vielen Dank.
Antworten:
Es gibt keine Möglichkeit, aktiv zu erkennen, ob ein Zoom vorhanden ist. Ich habe hier einen guten Eintrag gefunden, wie Sie versuchen können, ihn zu implementieren.
Ich habe zwei Möglichkeiten gefunden, um die Zoomstufe zu erkennen. Eine Möglichkeit, Änderungen der Zoomstufe zu erkennen, besteht darin, dass Prozentwerte nicht gezoomt werden. Ein Prozentwert ist relativ zur Breite des Ansichtsfensters und wird daher vom Seitenzoom nicht beeinflusst. Wenn Sie zwei Elemente einfügen, eines mit einer Position in Prozent und eines mit derselben Position in Pixel, werden sie beim Zoomen der Seite auseinander verschoben. Finden Sie das Verhältnis zwischen den Positionen beider Elemente und Sie haben die Zoomstufe. Siehe Testfall. http://web.archive.org/web/20080723161031/http://novemberborn.net/javascript/page-zoom-ff3
Sie können dies auch mit den Tools des obigen Beitrags tun. Das Problem ist, dass Sie mehr oder weniger fundierte Vermutungen anstellen, ob die Seite gezoomt wurde oder nicht. Dies funktioniert in einigen Browsern besser als in anderen.
Es gibt keine Möglichkeit festzustellen, ob die Seite gezoomt ist, wenn sie Ihre Seite beim Zoomen lädt.
document.body.offsetWidth
Ich verwende dieses JavaScript, um auf Zoom- "Ereignisse" zu reagieren.
Es fragt die Fensterbreite ab. (Wie auf dieser Seite etwas vorgeschlagen (auf die Ian Elliott verlinkt hat): http://novemberborn.net/javascript/page-zoom-ff3 [Archiv] )
Getestet mit Chrome, Firefox 3.6 und Opera, nicht mit IE.
Grüße, 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);
})();
Gute Nachrichten jedereinige Leute! Neuere Browser lösen ein Ereignis zum Ändern der Fenstergröße aus, wenn der Zoom geändert wird.
Definieren wir px_ratio wie folgt:
px-Verhältnis = Verhältnis von physischem Pixel zu CSS-px.
Wenn eine Seite gezoomt wird, werden die Pixel des Ansichtsfensters (px unterscheidet sich von Pixel) verringert und sollten an den Bildschirm angepasst werden, damit das Verhältnis (physisches Pixel / CSS_px) größer wird.
Beim Ändern der Fenstergröße wird jedoch die Bildschirmgröße ebenso reduziert wie die Pixel. so bleibt das Verhältnis erhalten.
aber
Größenänderung: Windows.resize-Ereignis auslösen -> ändert px_ratio nicht
//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;
}
}
Der entscheidende Punkt ist der Unterschied zwischen CSS PX und Physical Pixel.
https://gist.github.com/abilogos/66aba96bb0fb27ab3ed4a13245817d1e
Das funktioniert bei mir:
var deviceXDPI = screen.deviceXDPI;
setInterval(function(){
if(screen.deviceXDPI != deviceXDPI){
deviceXDPI = screen.deviceXDPI;
... there was a resize ...
}
}, 500);
Es wird nur auf IE8 benötigt. Alle anderen Browser generieren natürlich ein Größenänderungsereignis.
Es gibt ein geschicktes Plugin yonran
, das die Erkennung übernimmt . Hier ist seine zuvor beantwortete Frage zu StackOverflow. Es funktioniert für die meisten Browser. Die Anwendung ist so einfach:
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
Schaltfläche in der Option Eingabehilfen. Die Demo reagiert nicht auf die Änderung.
Ich möchte eine Verbesserung der vorherigen Lösung vorschlagen, indem Änderungen an der Fensterbreite nachverfolgt werden. Anstatt Ihr eigenes Array von Ereignis-Listenern beizubehalten, können Sie das vorhandene Javascript-Ereignissystem verwenden und bei einer Änderung der Breite Ihr eigenes Ereignis auslösen und Ereignishandler daran binden.
$(window).bind('myZoomEvent', function() { ... });
function pollZoomFireEvent()
{
if ( ... width changed ... ) {
$(window).trigger('myZoomEvent');
}
}
Gas / Entprellen kann dabei helfen, die Anrufrate Ihres Handlers zu reduzieren.
Sie können auch die Größenänderung des Texts und den Zoomfaktor abrufen, indem Sie ein Div einfügen, das mindestens einen nicht unterbrechbaren Bereich (möglicherweise ausgeblendet) enthält, und dessen Höhe regelmäßig überprüfen. Wenn sich die Höhe ändert, hat sich die Textgröße geändert (und Sie wissen, wie viel - dies wird übrigens auch ausgelöst, wenn das Fenster im Ganzseitenmodus gezoomt wird und Sie immer noch den richtigen Zoomfaktor bei gleicher Höhe / erhalten Höhenverhältnis).
<script>
var zoomv = function() {
if(topRightqs.style.width=='200px){
alert ("zoom");
}
};
zoomv();
</script>
Unter iOS 10 ist es möglich, dem touchmove
Ereignis einen Ereignis-Listener hinzuzufügen und festzustellen, ob die Seite mit dem aktuellen Ereignis gezoomt wurde.
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;
});
Obwohl dies eine 9 Jahre alte Frage ist, bleibt das Problem bestehen!
Ich habe die Größenänderung erkannt, während ich das Zoomen in einem Projekt ausgeschlossen habe. Daher habe ich meinen Code so bearbeitet, dass sowohl die Größenänderung als auch das Zoomen exklusiv voneinander erkannt werden. Es funktioniert die meiste Zeit, also wenn die meisten für Ihr Projekt gut genug ist, sollte dies hilfreich sein! Es erkennt 100% der Zeit das Zoomen in dem, was ich bisher getestet habe. Das einzige Problem ist, dass wenn der Benutzer verrückt wird (dh das Fenster spastisch in der Größe ändert) oder das Fenster verzögert wird, es möglicherweise als Zoom anstelle einer Fenstergröße ausgelöst wird.
Es erkennt eine Änderung der Größe window.outerWidth
oder window.outerHeight
als Fenstergröße, während eine Änderung der Fenstergröße window.innerWidth
oder window.innerHeight
unabhängig von der Fenstergröße als Zoom erkannt wird.
//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);
Hinweis: Meine Lösung ist wie die von KajMagnus, aber das hat bei mir besser funktioniert.
0.05
ohne zumindest eine gute Erklärung zu liefern. ;-) Ich weiß zum Beispiel, dass 10% in Chrome der kleinste Betrag ist, den der Browser auf jeden Fall zoomt, aber es ist nicht klar, dass dies für andere Browser gilt. Stellen Sie immer sicher, dass Ihr Code getestet wird, und seien Sie bereit, ihn zu verteidigen oder zu verbessern.
Hier ist eine saubere Lösung:
// 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);
});
Das Größenänderungsereignis funktioniert in modernen Browsern, indem das Ereignis angehängtwindow
und dann die Werte des body
oder eines anderen Elements mit beispielsweise ( angehängt .getBoundingClientRect () ) gelesen werden .
In einigen früheren Browsern war es möglich, Größenbehandlungsereignishandler für jedes HTML-Element zu registrieren. Es ist weiterhin möglich, Attribute für die Größenänderung festzulegen oder mit addEventListener () einen Handler für ein beliebiges Element festzulegen. Größenänderungsereignisse werden jedoch nur für das Fensterobjekt ausgelöst (dh von document.defaultView zurückgegeben). Nur für das Fensterobjekt registrierte Handler erhalten Größenänderungsereignisse .
window.addEventListener("resize", getSizes, false)
function getSizes(){
let body = document.body
console.log(body.clientWidth +"px x "+ body.clientHeight + "px")
}
Eine andere Alternative : die ResizeObserver-API
Abhängig von Ihrem Layout können Sie darauf achten, die Größe eines bestimmten Elements zu ändern.
Dies funktioniert gut bei «reaktionsschnellen» Layouts, da die Größe der Containerbox beim Zoomen geändert wird.
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>
Achten Sie darauf , Javascript-Aufgaben nicht durch Benutzergestenereignisse zu überladen. Verwenden Sie requestAnimationFrame, wenn Sie Neuzeichnungen benötigen.
Laut MDN ist "matchMedia" der richtige Weg, dies zu tun. Https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#Monitoring_screen_resolution_or_zoom_level_changes
Es ist ein bisschen pingelig, weil jede Instanz jeweils nur einen MQ sehen kann. Wenn Sie also daran interessiert sind einer Änderung der , müssen Sie eine Reihe von Übereinstimmungen vornehmen. Da der Browser jedoch für die Ausgabe der Ereignisse verantwortlich ist, ist dies wahrscheinlich Noch leistungsfähiger als das Abrufen, und Sie können den Rückruf drosseln oder entprellen oder an einen Animationsrahmen oder etwas anderes anheften - hier ist eine Implementierung, die ziemlich bissig erscheint. Sie können jederzeit _throttle oder was auch immer eintauschen, wenn Sie bereits davon abhängig sind.
Führen Sie das Code-Snippet aus und zoomen Sie in Ihrem Browser hinein und heraus. Beachten Sie den aktualisierten Wert im Markup - ich habe dies nur in Firefox getestet! Ich weiß, ob Sie Probleme sehen.
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>
Ich antworte auf einen 3 Jahre alten Link, aber ich denke, hier ist eine akzeptablere Antwort.
Erstellen Sie eine CSS-Datei als,
@media screen and (max-width: 1000px)
{
// things you want to trigger when the screen is zoomed
}
Z.B:-
@media screen and (max-width: 1000px)
{
.classname
{
font-size:10px;
}
}
Mit dem obigen Code wird die Schriftgröße auf 10 Pixel festgelegt, wenn der Bildschirm auf ca. 125% gezoomt wird. Sie können nach unterschiedlichen Zoomstufen suchen, indem Sie den Wert von '1000px' ändern.
max-width
und dem Zoomverhältnis?