Jak wykryć poziom powiększenia strony we wszystkich nowoczesnych przeglądarkach?

310
  1. Jak mogę wykryć poziom powiększenia strony we wszystkich nowoczesnych przeglądarkach? Podczas gdy ten wątek mówi, jak to zrobić w IE7 i IE8, nie mogę znaleźć dobrego rozwiązania dla różnych przeglądarek.

  2. Firefox przechowuje poziom powiększenia strony dla przyszłego dostępu. Czy przy pierwszym ładowaniu strony będę w stanie uzyskać poziom powiększenia? Gdzieś przeczytałem, że działa, gdy po załadowaniu strony następuje zmiana powiększenia .

  3. Czy istnieje sposób na złapanie 'zoom'zdarzenia?

Potrzebuję tego, ponieważ niektóre z moich obliczeń są oparte na pikselach i mogą się wahać po powiększeniu.


Zmodyfikowana próbka podana przez @tfl

Ta strona ostrzega o różnych wartościach wysokości po powiększeniu. [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>
rozumować
źródło
1
Zasadniczo chcę poznać wymiar DIV przy 100% powiększeniu.
understack
4
Zasadniczo nie można wykryć powiększenia w 2019 roku : przetestowałem wszystkie poniższe rozwiązania w Chrome 78 na Mac Catalina i żadne z nich nie działało.
collimarco

Odpowiedzi:

274

Teraz jest jeszcze większy bałagan niż wtedy, gdy zadawano to pytanie po raz pierwszy. Poniżej przeczytałem wszystkie odpowiedzi i posty na blogu, które mogłem znaleźć. Skonfigurowałem również tę stronę, aby przetestować wszystkie te metody pomiaru poziomu powiększenia .

Edycja (12.12.2011): Dodałem projekt, który można sklonować: https://github.com/tombigel/detect-zoom

  • IE8 : screen.deviceXDPI / screen.logicalXDPI(lub, dla poziomu powiększenia względem domyślnego,screen.systemXDPI / screen.logicalXDPI )
  • IE7 : var body = document.body,r = body.getBoundingClientRect(); return (r.left-r.right)/body.offsetWidth;(dzięki temu przykładowi lub tej odpowiedzi )
  • TYLKO FF3.5 : screen.width/ szerokość ekranu zapytania o media (patrz poniżej) (wykorzystuje fakt, że screen.widthużywa pikseli urządzenia, ale szerokość MQ używa pikseli CSS - dzięki szerokości trybu Quirksmode )
  • FF3.6 : brak znanej metody
  • FF4 + : wyszukiwanie binarne zapytań o media (patrz poniżej)
  • WebKit : https://www.chromestatus.com/feature/5737866978131968 (dzięki Teo w komentarzach)
  • WebKit : zmierzyć preferowany rozmiar div za pomocą -webkit-text-size-adjust:none.
  • WebKit : (zepsuty od r72591 ) document.width / jQuery(document).width()(dzięki Dirk van Oosterbosch powyżej ). Aby uzyskać stosunek wyrażony w pikselach urządzenia (zamiast w stosunku do domyślnego powiększenia), pomnóż przez window.devicePixelRatio.
  • Stary WebKit? (niezweryfikowany): parseInt(getComputedStyle(document.documentElement,null).width) / document.documentElement.clientWidth(z tej odpowiedzi )
  • Opera : document.documentElement.offsetWidth/ szerokość position:fixed; width:100%div. stąd ( tabela szerokości Quirksmode mówi, że to błąd; wewnętrzna szerokość powinna wynosić CSS px). Używamy elementu position: fixed, aby uzyskać szerokość rzutni, w tym przestrzeń, w której znajdują się paski przewijania ; document.documentElement.clientWidth wyklucza tę szerokość. Jest to zerwane od czasu w 2011 roku; Nie wiem już, jak uzyskać poziom powiększenia w Operze.
  • Inne : Rozwiązanie Flash od Sebastiana
  • Niewiarygodne: słuchaj zdarzeń myszy i mierz zmianę w screenX / zmianę w clientX

Oto wyszukiwanie binarne Firefoksa 4, ponieważ nie znam żadnej zmiennej, w której jest on ujawniony:

<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
źródło
1
Bardzo dobra robota, chociaż nie działa to dla mnie w IE 8.0.7601.17514 (najnowszy). Czy jest jakaś szansa na podsumowanie tego wszystkiego w jednej funkcji getZoom (), która działa we wszystkich przeglądarkach? Być może wydany również jako wtyczka jQuery? Znowu dobra robota.
ripper234
1
@yonran great plugin !, Ale to nie działa w IE9 powinno być zoom: screen.deviceXDPI / screen.logicalXDPI,zamiastzoom: screen.systemXDPI / screen.logicalXDPI,
Daniel
1
@RobW, kiedy napisałem to po raz pierwszy dla Firefoksa 4, Firefox nie miał matchMedia. Paul Irish napisał również podobny polifill matchMedia, który jest częścią Modernizr .
yonran
7
Dobre wieści wszyscy! W końcu to zrobili! Vieport API! chromestatus.com/feature/5737866978131968 Testuję to, świetne rzeczy!
Teo
3
Viewport API działa tylko w przypadku powiększania szczypta; jeśli powiększysz na pulpicie, zobaczysz, że skala wynosi 1. @Jason T Featheringham istnieją powody inne niż „dyskryminacja”, aby chcieć poznać poziom powiększenia. Zoom jest ustawiony na wszystkich stronach dla domeny, ale możesz chcieć obsługiwać go inaczej na stronie gry lub w wyskakującym okienku rozszerzenia niż na stronie pomocy.
Pudica
61

Możesz spróbować

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

To da ci procentowy poziom powiększenia przeglądarki na wyświetlaczach innych niż siatkówka. W przypadku wyświetlaczy o wysokiej DPI / siatkówce dawałoby to różne wartości (np. 200 dla Chrome i Safari, 140 dla Firefoxa).

Aby złapać zdarzenie powiększenia, możesz użyć

$(window).resize(function() { 
// your code 
});
użytkownik1080381
źródło
1
Działa idealnie, również na urządzeniach mobilnych. Interesujące jest również to, co mają urządzenia mobilne devicePixelRatio. To również bardzo pomogło mi przełączyć fixedelement na absolutepozycjonowany element po wystąpieniu zdarzenia powiększenia lub gdy początkowa wartość devicePixelRatiozmian. Doskonały! Dziękuję Ci!!
lowtechsun
12
Nie działa zgodnie z oczekiwaniami: zwraca 200 w Chrome na MacBooku z siatkówką, gdy przeglądarka nie jest powiększona.
Terite
19
Przeglądarki z obsługą ekranów o wysokiej rozdzielczości nie zapewnią oczekiwanego rezultatu podczas korzystania z takiego wyświetlacza, podobnie jak Safari, niezależnie od wyświetlacza.
Fredrik C
Tylko dla każdego, kogo to obchodzi, w IE działa to tylko w IE11 (zwróci NaN na IE10 lub niższej)
scunliffe
3
Math.round(window.devicePixelRatio * 100)działa w Chrome, IE, Edge i Firefox. Safari na iMac zawsze zwraca 200.
Super Jade
45

Dla mnie w przypadku Chrome / Webkit document.width / jQuery(document).width()nie działał. Kiedy document.width / jQuery(document).width()zmniejszyłem okno i powiększyłem stronę tak, aby pojawiały się poziome paski przewijania, nie były równe 1 przy domyślnym powiększeniu. Jest tak, ponieważ document.widthzawiera część dokumentu poza oknem ekranu.

Korzystanie window.innerWidthi window.outerWidthdziałało. Z jakiegoś powodu w Chrome zewnętrzna szerokość jest mierzona w pikselach ekranu, a wewnętrzna szerokość w pikselach 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";
}
użytkownik800583
źródło
1
Bardzo dobrze. A jeśli potrzebujesz tylko wiedzieć, czy jest on powiększony, czy nie w Chrome:isZoomed = (screenCssPixelRatio < .98 || screenCssPixelRatio > 1.02)
Brent Faust,
1
Cóż, window.outerWidth zmienia się również wraz z powiększeniem. Ponadto, nie w każdym systemie operacyjnym szerokość obramowania okna wynosi 8 pikseli (nawet w tym samym systemie operacyjnym projekt może się różnić). Proponuję jednak odjąć 16, a nie 8, ponieważ masz dwa razy obramowania okna. Ponadto niektóre przeglądarki mają obramowanie w ich rzeczywistym oknie renderowania (jak FF), a niektóre nie (Safari) - ale nawet to zależy od systemu operacyjnego, w którym korzystasz z przeglądarki (np. Safari ma ramkę w systemie Windows). Utworzenie kopii zapasowej początkowej szerokości wewnętrznej (np. Przy ładowaniu strony) i użycie jej do porównania działa lepiej, ale tylko wtedy, gdy wstępne powiększenie wynosiło 100% ...
StanE
1
Wyjścia 0 bez względu na to, co dla mnie (2017, luty).
Tiberiu-Ionuț Stan
1
switchinstrukcja może być lepsza niż wiele instrukcji if, jeśli.
Edric
Nie działa: po prostu przetestowano na Chrome na Macu i zawsze zwraca ten sam współczynnik, niezależnie od poziomu powiększenia
Collimarco
16

Mój współpracownik i ja użyliśmy skryptu z https://github.com/tombigel/detect-zoom . Ponadto dynamicznie utworzyliśmy element svg i sprawdziliśmy jego właściwość currentScale. Działa świetnie w Chrome i prawdopodobnie w większości przeglądarek. W FF funkcja „tylko powiększanie tekstu” musi być jednak wyłączona. SVG jest obsługiwany w większości przeglądarek. W chwili pisania tego tekstu testowałem na IE10, FF19 i 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);
Sójka
źródło
Ta metoda teraz zawsze zgłasza svg.currentScale = 1 w Firefox 29. Prawdopodobnie dlatego, że zmieniają rozmiar całego ekranu na podstawie powiększenia, które jest błędem . Wygląda na to, że IE11 ma ten sam problem na pulpicie, gdy wysokość ekranu jest dopasowana do urządzenia rzutni PixelRatio, które jest dość spieprzone.
hexalys
11

Ten artykuł był dla mnie niezwykle pomocny. Ogromne podziękowania dla Yonran. Chciałem przekazać dodatkowe informacje, które znalazłem, wdrażając niektóre z dostarczonych przez niego technik. W FF6 i Chrome 9 dodano obsługę zapytań o media z JS, co może znacznie uprościć podejście do zapytań o media niezbędne do określenia powiększenia FF. Zobacz dokumenty w MDN tutaj . Do moich celów musiałem jedynie wykryć, czy przeglądarka została powiększona, czy nie, nie potrzebowałem rzeczywistego współczynnika powiększenia. Udało mi się uzyskać odpowiedź za pomocą jednego wiersza kodu JavaScript:

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

Łącząc to z rozwiązaniami IE8 + i Webkit, które były również pojedynczymi liniami, byłem w stanie wykryć powiększenie w zdecydowanej większości przeglądarek uderzających w naszą aplikację za pomocą zaledwie kilku linii kodu.

brianh
źródło
4
Czy możesz podać kod, jak wykryć rzeczywiste powiększenie za pomocą zapytania medialnego?
TN.
Spróbuj użyć tylko „(szerokość: <X> px) i (wysokość: <Y> px)”, gdzie <X> i <Y> to odpowiednio window.innerWidth i window.innerHeight. Działa nawet przy bardzo małych powiększeniach. Działa również w Safari.
maks.
@max Czy możesz podać JSFIddle lub przykładowy kod tego, jak to wygląda razem, proszę?
lowtechsun
Zawsze zgłasza prawdziwe na urządzeniach z siatkówką, takich jak Macbook Pro.
Matthew Sanders
codepen.io/anon/pen/LgrGjJ pokazuje wyszukiwanie binarne z zapytaniami medialnymi, ale jest to to samo, co zapytanie devicePixelRatio: bierze pod uwagę skalowanie wyświetlania.
ZachB
11
zoom = ( window.outerWidth - 10 ) / window.innerWidth

To wszystko czego potrzebujesz.

Alex von Thorn
źródło
Dlaczego odjąć 10od outerWidth?
callum
Prawdopodobnie dla paska przewijania. Każdy pasek przewijania również jest inny, podobnie jak w iOS jest znacznie mniejszy. Plus to rozwiązanie wydaje się być tylko chromem
Sarah
1
To nie działa, jeśli użytkownik ma pasek boczny, taki jak zakładki w FF
Gerrit Sedlaczek
7

Mam na to rozwiązanie od stycznia 2016 r. Testowane w przeglądarkach Chrome, Firefox i MS Edge.

Zasada jest następująca. Zbierz 2 punkty MouseEvent, które są daleko od siebie. Każde zdarzenie myszy ma współrzędne ekranu i dokumentu. Zmierz odległość między 2 punktami w obu układach współrzędnych. Chociaż istnieją różne stałe przesunięcia między układami współrzędnych wynikające z umeblowania przeglądarki, odległość między punktami powinna być identyczna, jeśli strona nie zostanie powiększona. Powodem określenia „daleko od siebie” (ustawiłem to jako 12 pikseli) jest to, że małe zmiany zoomu (np. 90% lub 110%) są wykrywalne.

Odniesienie: https://developer.mozilla.org/en/docs/Web/Events/mousemove

Kroki:

  1. Dodaj detektor ruchu myszy

    window.addEventListener("mousemove", function(event) {
        // handle event
    });
  2. Przechwyć 4 pomiary ze zdarzeń myszy:

    event.clientX, event.clientY, event.screenX, event.screenY
  3. Zmierz odległość d_c między 2 punktami w systemie klienta

  4. Zmierz odległość d_s między 2 punktami w systemie ekranowym

  5. Jeśli d_c! = D_s, wówczas zastosowane zostanie powiększenie. Różnica między nimi mówi o powiększeniu.

Uwaga: Obliczenia odległości wykonuj tylko rzadko, np. Kiedy możesz próbkować nowe zdarzenie myszy, które jest dalekie od poprzedniego.

Ograniczenia: Zakłada, że ​​użytkownik przynajmniej trochę poruszy myszką, a zoom jest do tej pory nieznany.

użytkownik1191311
źródło
1
Stworzyłem skrzypce: jsfiddle.net/Terite/9b6ko854 z „daleko od siebie” oznaczonymi jako 100 pikseli. Niestety działa on niestabilnie w przeglądarce Firefox (52) na MacBooku z wyświetlaczem Retina. Należy również zauważyć, że powiększenie interfejsu Windows 7 125% jest wykrywane w Chrome, Firefox i IE11 (w powiększeniu 125%, co jest wówczas domyślne) jako powiększenie przeglądarki.
Terite
Twoje skrzypce działa dla mnie, przetestowane w systemie Linux z przeglądarkami Firefox i Chrome :)
user1191311
Wyświetlacze Retina stanowią kolejny poziom trudności, ponieważ między innymi nieprawidłowo zgłaszają rozmiary pikseli.
user1191311
5

Możesz użyć Visual Viewport API :

window.visualViewport.scale;

Jest to standard i działa zarówno na komputerze, jak i telefonie komórkowym: obsługa przeglądarki .

Collimarco
źródło
Wygląda na przydatny, ale nadal jest domyślnie wyłączony na pulpicie Firefoksa i nie działa w Internet Explorerze od 31.05.20.
derekbaker783
3

W Internet Explorerze 7, 8 i 9 działa to:

function getZoom() {
    var screen;

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

Dodawane jest „+0,9”, aby zapobiec błędom zaokrąglania (w przeciwnym razie uzyskasz 104% i 109%, gdy powiększenie przeglądarki jest ustawione odpowiednio na 105% i 110%).

W IE6 powiększenie nie istnieje, więc sprawdzanie powiększenia nie jest konieczne.

kłopot
źródło
1
Ciekawy. Dla mnie zawsze pokazuje 80% powiększenia ... Myślę, że dzieje się tak, ponieważ mam ustawione duże czcionki na poziomie Windows 7 (wyszukaj „rozmiar czcionki” w panelu sterowania). To lepsze niż rozwiązanie IE8 w odpowiedzi @ yonran, które w ogóle nie działało dla mnie. jsbin.com/obowof
ripper234
Dostaję 101%, gdy zoom jest ustawiony na 100%.
Allen Wallace
Ja też. użyj 0,4999 zamiast 0,9
yan bellavance
ieZoomLevel = ((screen.deviceXDPI / screen.systemXDPI) * 100 + 0,4999) .toFixed ();
yan bellavance
3

Wymyśliłem:

1) Zrób position:fixed <div>z width:100%( id = zoomdiv )

2) po załadowaniu strony:

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

I działało dla mnie ctrl+i ctrl-zoomów.

lub mogę dodać linię do $(window).onresize()wydarzenia, aby uzyskać aktywny poziom powiększenia


Kod:

<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: to mój pierwszy post, przepraszam za błędy

Abhishek Borar
źródło
3
Niestety zadziała to tylko wtedy, gdy użytkownik ma zmaksymalizowaną przeglądarkę ( screen.availWidthzgłasza szerokość ekranu w pikselach ekranu, a nie okno przeglądarki).
Bailey Parker,
3

Działa to świetnie dla mnie w przeglądarkach internetowych (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;
}

Wydaje się jednak, że nie działa w przeglądarce Firefox.

Działa to również w WebKit:

var zoomLevel = document.width / document.body.clientWidth;
rudolfrck
źródło
5
document.widthpowraca niezdefiniowany
Adam
Zawsze zwraca wartość true bez względu na powiększenie (2017, luty, wyświetlanie siatkówki).
Tiberiu-Ionuț Stan
3

Zasadniczo mamy:

  • window.devicePixelRatioktóry uwzględnia zarówno powiększenie na poziomie przeglądarki *, jak i powiększenie systemowe / gęstość pikseli.
    * - w komputerach Mac / Safari poziom powiększenia nie jest brany pod uwagę
  • zapytania o media
  • vw/ vhJednostki CSS
  • resize zdarzenie, które jest wyzwalane przy zmianie poziomu powiększenia, powoduje efektywny rozmiar zmian okna

to powinno wystarczyć dla normalnego UX. Jeśli musisz wykryć poziom powiększenia, może to oznaczać zły projekt interfejsu użytkownika.

Pitch-zoom jest trudniejszy do śledzenia i nie jest obecnie rozważany.

kirilloid
źródło
1
window.devicePixelRatio to dobra odpowiedź, która działa w najnowszej wersji głównych przeglądarek - Chrome, Safari, FF, Edge, IE
DShultz
@kirilloid czy znalazłeś coś, co można by wykorzystać do wiarygodnego znalezienia „poziomu powiększenia” w Safari?
onassar
1

Twoje obliczenia są nadal oparte na liczbie pikseli CSS. Teraz mają tylko inny rozmiar na ekranie. To jest punkt pełnego powiększenia strony.

Co chciałbyś zrobić w przeglądarce na urządzeniu 192dpi, które zwykle wyświetla cztery piksele urządzenia na każdy piksel obrazu? Przy powiększeniu 50% urządzenie wyświetla teraz jeden piksel obrazu w jednym pikselu urządzenia.

Neil
źródło
@Neil: jak mogę uzyskać wymiary „pikseli CSS”?
understack
Domyślnie CSS wskazuje na punkty, ale możesz oczywiście określić piksele za pomocą modyfikatora wymiaru px. Jeśli chodzi o właściwości elementu pobrane w JavaScript, to powinny już być w pikselach CSS. Jeśli więc określisz szerokość <div> na 100px, to otrzymasz to z JavaScript, niezależnie od poziomu powiększenia.
Neil,
1

W Chrome

var ratio = (screen.availWidth / document.documentElement.clientWidth);
var zoomLevel = Number(ratio.toFixed(1).replace(".", "") + "0");
Nicolas Giszpenc
źródło
1
Działa tylko wtedy, gdy okno przeglądarki ma pełną szerokość ekranu.
tenbits,
0

Nie przetestowałem tego dla IE, ale jeśli utworzysz element za elempomocą

min-width: 100%

następnie

window.document.width / elem.clientWidth

poda poziom powiększenia przeglądarki (w tym document.body.style.zoomwspółczynnik).

Dirk van Oosterbosch
źródło
Testowałem to, ale powiększanie nie wydaje się zwiększać elem.clientWidth
Tom
0

To jest dla Chrome , po odpowiedzi użytkownika 800583 ...

Spędziłem kilka godzin na tym problemie i nie znalazłem lepszego podejścia, ale:

  • Istnieje 16 „zoomLevel”, a nie 10
  • Gdy Chrome jest w trybie pełnoekranowym / zmaksymalizowany, stosunek jest window.outerWidth/window.innerWidth, a gdy nie jest, wydaje się, że stosunek jest (window.outerWidth-16)/window.innerWidth, jednak do pierwszego przypadku można podejść przez drugi.

Więc doszedłem do następujących ...

Ale to podejście ma ograniczenia: na przykład, jeśli grasz na akordeonie z oknem aplikacji (szybko powiększaj i zmniejszaj szerokość okna), dostaniesz przerwy między poziomami powiększenia, chociaż powiększenie się nie zmieniło (może to być szerokość zewnętrzna i szerokość wewnętrzna nie są dokładnie zaktualizowane w tym samym czasie).

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

A jeśli chcesz czynnik:

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
źródło
Miałem problemy z „window.outerWidth / window.innerWidth”, który również podał mi niewłaściwą wartość, co mogło być spowodowane tym, że byłem w ramce iframe. Więc użyłem okna nadrzędnego i dało ono prawidłową odpowiedź: window.parent.window.outerWidth / window.parent.window.innerWidth
yan bellavance
0

Mam to rozwiązanie tylko na urządzenia mobilne (testowane na Androidzie):

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());

});

Jeśli chcesz uzyskać poziom powiększenia zaraz po przesunięciu szczypta, prawdopodobnie będziesz musiał ustawić mały limit czasu ze względu na opóźnienie renderowania (ale nie jestem pewien, ponieważ go nie przetestowałem).

pmrotule
źródło
0

Ta odpowiedź jest oparta na komentarzach na temat niepoprawnego powrotu devicePixelRatio do odpowiedzi user1080381.

Zauważyłem, że to polecenie wracało niepoprawnie również w niektórych przypadkach podczas pracy z komputerem stacjonarnym, Surface Pro 3 i Surface Pro 4.

Odkryłem, że działa na moim pulpicie, ale SP3 i SP4 podają różne liczby od siebie i na pulpicie.

Zauważyłem jednak, że SP3 wraca jako 1 i pół razy większy niż oczekiwany poziom powiększenia. Kiedy spojrzałem na ustawienia ekranu, SP3 był ustawiony na 150% zamiast 100%, które miałem na pulpicie.

Tak więc rozwiązaniem komentarzy powinno być podzielenie zwróconego poziomu powiększenia przez skalę aktualnie używanej maszyny.

Byłem w stanie uzyskać skalę w ustawieniach systemu Windows, wykonując następujące czynności:

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

Tak więc w przypadku mojego SP3, tak wygląda ten kod przy 100% powiększeniu:

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

Pomnożenie przez 100 w pierwotnej odpowiedzi użytkownika1080381 dałoby wtedy powiększenie 100 (%).

Cameron Weaver
źródło
0

Czy obecnie działa, ale nadal trzeba go rozdzielić według przeglądarki. Testy zakończyły się pomyślnie w Chrome (75) i Safari (11.1) (jak dotąd nie znalazłem sposobu na FF). Uzyskuje również prawidłową wartość powiększenia na wyświetlaczu siatkówki, a obliczenia są uruchamiane po zdarzeniu zmiany rozmiaru.

    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()
    };
  }
Jog
źródło
-1

tutaj to się nie zmienia !:

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

utwórz prosty plik HTML, kliknij przycisk. bez względu na poziom powiększenia: pokaże ci szerokość 400px (przynajmniej z Firefoxem i ie8)


źródło
@tfl: to dlatego, że poprawiłeś szerokość w stylu wstawiania. Zmodyfikowałem twoją próbkę, aby pokazać moją skrzynkę (zamieszczoną w oryginalnym pytaniu).
understack
-1

To może, ale nie musi nikomu pomóc, ale miałem stronę, której nie mogłem poprawnie wyśrodkować, bez względu na to, jakie sztuczki CSS próbowałem, więc napisałem stronę wywoławczą pliku JQuery:

Wystąpił problem z poziomem powiększenia przeglądarki, strona przesuwałaby się na podstawie 100%, 125%, 150% itd.

Poniższy kod znajduje się w pliku JQuery o nazwie centerpage.js.

Z mojej strony musiałem link do JQuery i tego pliku, aby działał, mimo że moja strona wzorcowa miała już link do 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();
});

Również jeśli chcesz wyśrodkować panel:

// 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);
    }
}
użytkownik1054326
źródło
-1

To pytanie zostało postawione jak przed wiekami, ale dzisiaj, gdy szukałem tej samej odpowiedzi „Jak wykryć powiększenie i pomniejszenie”, nie mogłem znaleźć jednej odpowiedzi, która pasowałaby do wszystkich przeglądarek.

Jak na razie: w Firefox / Chrome / IE8 i IE9 powiększanie i pomniejszanie wywołuje zdarzenie window.resize. Można to zrobić za pomocą:

$(window).resize(function() {
//YOUR CODE.
});
Bhumi Singhal
źródło
-1

Obejście dla FireFox 16+, aby znaleźć DPPX (poziom powiększenia) wyłącznie w 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);
leksykon
źródło
Nie działa zgodnie z oczekiwaniami w przeglądarce Firefox (52) na MacBooku z wyświetlaczem Retina - zwraca 2, gdy nie ma powiększenia. Stworzyłem skrzypce: 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
źródło
6
Wyjaśnij również, jak działa Twój kod. Będzie to pomocne, jeśli jakiś nowicjusz znajdzie odpowiedź.
displayName
Stworzyłem skrzypce: jsfiddle.net/Terite/5n1bk9do As @AlexeySh. wspomniane, nie działa zgodnie z oczekiwaniami na wyświetlaczu Retina w Chrome (56), Firefox (52). Pokazuje także 0 w powiększeniu w Safari (10).
Terite
-1

Problem leży w rodzaju zastosowanego monitora, monitorze 4k w porównaniu ze standardowym monitorem. Chrome jest zdecydowanie najmądrzejszy, jeśli chodzi o to, aby powiedzieć nam, jaki jest poziom powiększenia, po prostu za pomocą window.devicePixelRatio, najwyraźniej może powiedzieć, jaka jest gęstość pikseli i zgłasza tę samą liczbę, bez względu na wszystko.

Inne przeglądarki, nie tak bardzo. IE i Edge są prawdopodobnie najgorsze, ponieważ radzą sobie z różnymi poziomami powiększenia. Aby uzyskać tekst o tym samym rozmiarze na monitorze 4k, musisz wybrać 200% zamiast 100% na standardowym monitorze.

Od maja 2018 r. Oto, co muszę wykryć poziomy powiększenia dla kilku najpopularniejszych przeglądarek, Chrome, Firefox i IE11. Powiedz mi, jaki jest procent powiększenia. W przypadku IE zgłasza 100%, nawet dla monitorów 4k, które w rzeczywistości mają 200%, ale rozmiar tekstu jest naprawdę taki sam.

Oto skrzypce: https://jsfiddle.net/ae1hdogr/

Jeśli ktoś zechce zrobić dźgnięcie nożem w innych przeglądarkach i zaktualizować skrzypce, zrób to. Moim głównym celem było objęcie tych 3 przeglądarek wykrywaniem, czy ludzie używają współczynnika powiększenia większego niż 100%, aby korzystać z mojej aplikacji internetowej i wyświetlać powiadomienie sugerujące współczynnik powiększenia leasingodawcy.

Bill_VA
źródło
Safari na Mac Book Pro (ekran Retina) zwraca 0, Chrome na ekranie innym niż Retina zwraca poprawnie 100, 90 itd.
OZZIE 18.10.18
Zwraca 200 na ekranie Retina z Chrome i Firefox
OZZIE