Как определить уровень масштабирования страницы во всех современных браузерах?

310
  1. Как определить уровень масштабирования страницы во всех современных браузерах? Хотя в этой теме рассказывается, как это сделать в IE7 и IE8, я не могу найти хорошего кросс-браузерного решения.

  2. Firefox сохраняет уровень масштабирования страницы для последующего доступа. Смогу ли я получить уровень масштабирования при загрузке первой страницы? Где-то я читал, что это работает, когда изменение масштаба происходит после загрузки страницы.

  3. Есть ли способ отловить 'zoom'событие?

Мне это нужно, потому что некоторые из моих расчетов основаны на пикселях и могут изменяться при увеличении.


Модифицированный образец, данный @tfl

Эта страница предупреждает о различных значениях высоты при увеличении. [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>
understack
источник
1
В основном я хочу знать размер DIV при 100% увеличении.
Понять
4
По сути, в 2019 году нет способа обнаружить увеличение : я протестировал все приведенные ниже решения на Chrome 78 на Mac Catalina, и ни одно из них не сработало.
Коллимарко

Ответы:

274

Теперь это еще больший беспорядок, чем это было, когда этот вопрос был впервые задан. Прочитав все ответы и сообщения в блоге, которые я смог найти, вот краткое изложение. Я также настроил эту страницу, чтобы протестировать все эти методы измерения уровня масштабирования .

Изменить (2011-12-12): я добавил проект, который можно клонировать: https://github.com/tombigel/detect-zoom

  • IE8 : screen.deviceXDPI / screen.logicalXDPI(или для уровня масштабирования относительно масштаба по умолчанию screen.systemXDPI / screen.logicalXDPI)
  • IE7 : var body = document.body,r = body.getBoundingClientRect(); return (r.left-r.right)/body.offsetWidth;(благодаря этому примеру или этому ответу )
  • ТОЛЬКО для FF3.5 : screen.width/ ширина экрана медиа-запроса (см. Ниже) (используется тот факт, что screen.widthиспользуются пиксели устройства, но ширина MQ использует пиксели CSS - благодаря ширине Quirksmode )
  • FF3.6 : неизвестный метод
  • FF4 + : бинарный поиск в медиа-запросах (см. Ниже)
  • WebKit : https://www.chromestatus.com/feature/5737866978131968 (спасибо Тео в комментариях)
  • WebKit : измерьте предпочтительный размер div с помощью -webkit-text-size-adjust:none.
  • WebKit : (не работает с r72591 ) document.width / jQuery(document).width()(спасибо Дирку ван Остербошу выше ). Чтобы получить соотношение в пикселях устройства (вместо относительного увеличения по умолчанию), умножьте на window.devicePixelRatio.
  • Старый WebKit? (не проверено): parseInt(getComputedStyle(document.documentElement,null).width) / document.documentElement.clientWidth(из этого ответа )
  • Опера : document.documentElement.offsetWidth/ ширина position:fixed; width:100%деления. отсюда ( таблица ширины Quirksmode говорит, что это ошибка; innerWidth должен быть CSS px). Мы используем элемент position: fixed, чтобы получить ширину области просмотра, включая пространство, где находятся полосы прокрутки ; document.documentElement.clientWidth исключает эту ширину. Это сломано с 2011 года; Я не знаю способа получить уровень масштабирования в Opera больше.
  • Другое : Flash-решение от Себастьяна
  • Ненадежный: слушайте события мыши и измеряйте изменения в screenX / изменения в clientX

Вот бинарный поиск для Firefox 4, так как я не знаю ни одной переменной, где он представлен:

<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
источник
1
Очень хорошая работа, хотя у меня это не работает в IE 8.0.7601.17514 (последняя версия). Есть ли шанс обернуть все это в одну функцию getZoom (), которая работает во всех браузерах? Возможно также выпустить как плагин jQuery? Хорошая работа снова.
ripper234
1
@yonran отличный плагин !, но он не работает в IE9, он должен быть zoom: screen.deviceXDPI / screen.logicalXDPI,вместоzoom: screen.systemXDPI / screen.logicalXDPI,
Даниэль
1
@RobW, когда я впервые написал это для Firefox 4, Firefox не было matchMedia. Пол Ирриш также написал аналогичный matchMedia polyfill, который является частью Modernizr .
Йонран
7
Хорошие новости, все! Они наконец сделали это! Vieport API! chromestatus.com/feature/5737866978131968 Я проверяю это, отличные вещи!
Тео
3
API Viewport работает только для пинч-зума; если вы увеличиваете изображение на рабочем столе, оно говорит, что масштаб равен 1. @ Jason T Featheringham Существуют и другие причины, помимо «дискриминации», чтобы узнать уровень масштабирования. Масштаб устанавливается на всех страницах домена, но вы, возможно, захотите обращаться с ним по-другому на странице игры или во всплывающем окне расширения, чем на странице справки.
Pudica
61

Можешь попробовать

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

Это даст вам процент увеличения масштаба браузера на дисплеях без сетчатки. Для дисплеев с высоким DPI / сетчаткой он будет давать разные значения (например, 200 для Chrome и Safari, 140 для Firefox).

Чтобы поймать событие масштабирования вы можете использовать

$(window).resize(function() { 
// your code 
});
user1080381
источник
1
Отлично работает, в том числе и на мобильных устройствах. Также довольно интересно посмотреть, что есть у мобильных устройств devicePixelRatio. Это также очень помогло мне переключить fixedэлемент на элемент с absoluteположительным позиционированием, когда происходит событие масштабирования или когда изменяется начальное значение devicePixelRatio. Отлично! Спасибо!!
lowtechsun
12
Не работает должным образом: он возвращает 200 в Chrome на MacBook с сетчаткой, когда браузер не увеличен.
Terite
19
Браузеры с поддержкой экранов с высоким DPI не дадут ожидаемого результата при использовании такого дисплея, равно как и Safari, независимо от дисплея.
Фредрик С.
Просто для всех, кто заботится, на IE это работает только на IE11 (он вернет NaN на IE10 или ниже)
scunliffe
3
Math.round(window.devicePixelRatio * 100)работает на Chrome, IE, Edge и Firefox. Safari на iMac всегда возвращает 200.
Супер Джейд
45

Для меня, для Chrome / Webkit, document.width / jQuery(document).width()не сработало. Когда я уменьшил размер окна и увеличил масштаб моего сайта до появления горизонтальных полос прокрутки, он document.width / jQuery(document).width()не стал равным 1 при увеличении по умолчанию. Это потому, что document.widthвключает в себя часть документа за пределами области просмотра.

Используя window.innerWidthи window.outerWidthработал. По какой-то причине в Chrome externalWidth измеряется в пикселях экрана, а innerWidth измеряется в пикселях 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
источник
1
Очень хорошо. И если вам нужно только узнать, увеличен ли он в Chrome или нет:isZoomed = (screenCssPixelRatio < .98 || screenCssPixelRatio > 1.02)
Брент Фауст
1
Ну, window.outerWidth также изменяется с увеличением. Кроме того, не в каждой ОС ширина границы окна составляет 8 пикселей (даже в одной ОС дизайн может отличаться). Однако я бы предложил вычесть 16, а не 8, так как у вас есть границы окна дважды. Кроме того, некоторые браузеры имеют границу своего фактического окна рендеринга (например, FF), а некоторые нет (Safari) - но даже это зависит от того, в какой ОС вы используете браузер (например, Safari имеет границу в Windows). Резервное копирование начальной внутренней ширины (например, при загрузке страницы) и использование ее для сравнения работает лучше, но только если начальное увеличение было 100% ...
StanE
1
Выходы 0 независимо от того, что для меня (2017, февраль).
Tiberiu-Ionuț Stan
1
switchутверждение может быть лучше, чем многие, если еще заявления.
Эдрик
Это не работает: просто протестировано на Chrome на Mac и всегда возвращает одинаковое соотношение, независимо от уровня масштабирования
collimarco
16

Мой коллега и я использовали скрипт из https://github.com/tombigel/detect-zoom . Кроме того, мы также динамически создали элемент svg и проверили его свойство currentScale. Он отлично работает на Chrome и, вероятно, на большинстве браузеров. На FF функция «только масштабирование текста» должна быть отключена. SVG поддерживается в большинстве браузеров. На момент написания статьи проверялось на IE10, FF19 и 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);
сойка
источник
Этот метод теперь всегда сообщает svg.currentScale = 1 в Firefox 29. Возможно, потому что они изменяют размеры всего экрана на основе масштабирования, что является ошибкой . IE11, похоже, имеет ту же проблему на рабочем столе с высотой экрана, настроенной на viewport devicePixelRatio, которая довольно испорчена.
hexalys
11

Я нашел эту статью чрезвычайно полезной. Огромное спасибо Йонрану. Я хотел пройти некоторое дополнительное обучение, которое я нашел, внедряя некоторые из методов, которые он обеспечил. В FF6 и Chrome 9 была добавлена ​​поддержка медиазапросов из JS, что может значительно упростить подход к медиазапросам, необходимый для определения увеличения FF. Смотрите документы в MDN здесь . Для моих целей мне нужно было только определить, был ли браузер увеличен или уменьшен, мне не требовался фактический коэффициент увеличения. Я смог получить ответ с одной строкой JavaScript:

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

Комбинируя это с решениями IE8 + и Webkit, которые также были однострочными, я смог обнаружить увеличение в большинстве браузеров, попавших в наше приложение всего несколькими строками кода.

brianh
источник
4
Не могли бы вы предоставить код, как определить фактический масштаб с помощью медиа-запроса?
TN.
Попробуйте использовать только «(width: <X> px) и (height: <Y> px)», где <X> и <Y> - это window.innerWidth и window.innerHeight, соответственно. Это работает даже для очень маленького увеличения. Работает в Safari тоже.
максимум
@max. Можете ли вы предоставить JSFIddle или пример кода, как это выглядит вместе, пожалуйста?
lowtechsun
Всегда сообщает true на устройствах Retina, таких как MacBook Pro.
Мэтью Сандерс
codepen.io/anon/pen/LgrGjJ показывает бинарный поиск с медиа-запросами, но это то же самое, что и запросы devicePixelRatio: он учитывает масштабирование отображения.
ЗакБ
11
zoom = ( window.outerWidth - 10 ) / window.innerWidth

Это все, что вам нужно.

Алекс фон Торн
источник
Зачем вычитать 10из outerWidth?
Каллум
Вероятно, для полосы прокрутки. Каждая полоса прокрутки тоже отличается, как в iOS, она намного меньше. Плюс это решение, кажется, только хром
Сара
1
Это не работает, если у пользователя есть боковая панель, такая как закладки в FF
Gerrit Sedlaczek
7

У меня есть решение для этого с января 2016 года. Проверено на работу в браузерах Chrome, Firefox и MS Edge.

Принцип заключается в следующем. Соберите 2 очка MouseEvent, которые находятся далеко друг от друга. Каждое событие мыши имеет экран и координаты документа. Измерьте расстояние между двумя точками в обеих системах координат. Несмотря на то, что из-за мебели браузера существуют переменные фиксированные смещения между системами координат, расстояние между точками должно быть одинаковым, если страница не масштабирована. Причиной указания «далеко друг от друга» (я назвал это 12 пикселями) является то, что небольшие изменения масштаба (например, 90% или 110%) можно обнаружить.

Ссылка: https://developer.mozilla.org/en/docs/Web/Events/mousemove

шаги:

  1. Добавить слушателя перемещения мыши

    window.addEventListener("mousemove", function(event) {
        // handle event
    });
  2. Захват 4 измерений от событий мыши:

    event.clientX, event.clientY, event.screenX, event.screenY
  3. Измерьте расстояние d_c между двумя точками в клиентской системе

  4. Измерьте расстояние d_s между двумя точками в системе экранов

  5. Если d_c! = D_s, то применяется масштабирование. Разница между ними говорит о величине увеличения.

Обратите внимание, что вычисления расстояний выполняются редко, например, когда вы можете выбрать новое событие мыши, которое далеко от предыдущего.

Ограничения: Предполагается, что пользователь будет двигать мышь хотя бы немного, а масштаб до этого времени неизвестен.

user1191311
источник
1
Я создал скрипку: jsfiddle.net/Terite/9b6ko854 со значением "далеко друг от друга", означающим 100 пикселей. К сожалению, он работает нестабильно в Firefox (52) на MacBook с дисплеем сетчатки. Также следует отметить, что в Windows 7 масштабирование интерфейса 125% обнаруживается в Chrome, Firefox и IE11 (при масштабировании 125%, который тогда используется по умолчанию) в качестве увеличения браузера.
Terite
Ваша скрипка работает для меня, проверено в Linux с Firefox и Chrome :)
user1191311
Дисплеи Retina добавляют еще один уровень сложности, поскольку, помимо прочего, они неправильно сообщают о размерах пикселей.
user1191311
5

Вы можете использовать Visual Viewport API :

window.visualViewport.scale;

Он стандартный и работает как на настольном, так и на мобильном устройствах: поддержка браузера .

collimarco
источник
Выглядит удобно, но по-прежнему отключено по умолчанию на рабочем столе Firefox и не работает в Internet Explorer с 31.05.20.
derekbaker783
3

В Internet Explorer 7, 8 и 9 это работает:

function getZoom() {
    var screen;

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

«+0,9» добавлено для предотвращения ошибок округления (в противном случае вы получите 104% и 109%, если масштаб браузера установлен на 105% и 110% соответственно).

В IE6 масштабирования не существует, поэтому нет необходимости проверять масштаб.

Pench
источник
1
Интересный. Для меня это всегда показывает 80% увеличения ... Я полагаю, это потому, что у меня установлены большие шрифты на уровне Windows 7 (поиск "размер шрифта" на панели управления). Это лучше, чем решение IE8 в ответе @ yonran, которое у меня совсем не сработало. jsbin.com/obowof
ripper234
Я получаю 101%, когда зум установлен на 100%.
Аллен Уоллес
я тоже. используйте 0,4999 вместо 0,9
Ян Белванс
ieZoomLevel = ((screen.deviceXDPI / screen.systemXDPI) * 100 + 0,4999) .toFixed ();
Ян Беллаванс
3

Что я придумал, это:

1) Сделать position:fixed <div>с width:100%( id = zoomdiv )

2) когда страница загружается:

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

И это работает для меня ctrl+и ctrl-увеличивает.

или я могу добавить строку к $(window).onresize()событию, чтобы получить активный уровень масштабирования


Код:

<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: это мой первый пост, простите за любые ошибки

Абхишек Борар
источник
3
К сожалению, это будет работать только в том случае, если у пользователя развернут браузер ( screen.availWidthсообщает ширину экрана в пикселях экрана, а не в окне браузера).
Бейли Паркер
3

Это отлично работает для меня в браузерах на основе 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;
}

Похоже, не работает в Firefox.

Это также работает в WebKit:

var zoomLevel = document.width / document.body.clientWidth;
rudolfrck
источник
5
document.widthвозвращается не определено
Адам
Всегда возвращает true независимо от масштаба (2017, февраль, дисплей сетчатки).
Tiberiu-Ionuț Stan
3

В основном мы имеем:

  • window.devicePixelRatioкоторая учитывает как масштабирование на уровне браузера *, так и системное масштабирование / плотность пикселей.
    * - на Mac / Safari уровень масштабирования не учитывается
  • медиа-запросы
  • vw/ vhCSS единицы
  • resize событие, которое срабатывает при изменении уровня масштабирования, вызывает эффективный размер изменения окна

этого должно быть достаточно для нормального UX. Если вам нужно определить уровень масштабирования, это может быть признаком плохого дизайна пользовательского интерфейса.

Pitch-zoom сложнее отследить и в настоящее время не рассматривается.

kirilloid
источник
1
window.devicePixelRatio - хороший ответ, который работает в последних версиях основных браузеров - Chrome, Safari, FF, Edge, IE
DShultz
@kirilloid Вы нашли что-нибудь, что можно было бы использовать для надежного определения «уровня масштабирования» в Safari?
Онассар
2

На мобильных устройствах (с Chrome для Android или Opera Mobile) вы можете обнаружить увеличение по window.visualViewport.scale . https://developer.mozilla.org/en-US/docs/Web/API/Visual_Viewport_API

Определить в Safari: document.documentElement.clientWidth / window.innerWidth (возвращает 1, если на устройстве нет масштабирования).

Джим
источник
1

Ваши расчеты по-прежнему основаны на количестве пикселей CSS. Теперь они просто другого размера на экране. В этом смысл полного увеличения страницы.

Что бы вы хотели, чтобы происходило в браузере на устройстве с разрешением 192 точек на дюйм, которое обычно отображало четыре пикселя устройства для каждого пикселя изображения? При увеличении 50% это устройство теперь отображает один пиксель изображения в одном пикселе устройства.

Нил
источник
@Neil: как я могу получить размеры CSS-пикселей?
Понять
CSS по умолчанию указывает на точки, но вы, конечно, можете указать пиксели, используя модификатор размера px. Что касается свойств элементов, полученных в JavaScript, они уже должны быть в пикселях CSS. Поэтому, если вы укажете ширину <div> равной 100 пикселям, это то, что вы получите от JavaScript, каким бы ни был уровень масштабирования.
Нил
1

На Chrome

var ratio = (screen.availWidth / document.documentElement.clientWidth);
var zoomLevel = Number(ratio.toFixed(1).replace(".", "") + "0");
Николас Гишпенц
источник
1
Работает только тогда, когда окно браузера имеет полную ширину экрана.
tenbits
0

Не проверял это для IE, но если вы сделаете элемент elemс

min-width: 100%

затем

window.document.width / elem.clientWidth

даст вам уровень масштабирования вашего браузера (включая document.body.style.zoomфактор).

Дирк ван Оостербош
источник
Протестировано это, но увеличение не похоже на увеличение elem.clientWidth
Том
0

Это для Chrome , в ответ user800583 ответить ...

Я потратил несколько часов на эту проблему и не нашел лучшего подхода, но:

  • Есть 16 'zoomLevel', а не 10
  • Когда Chrome является полноэкранным / максимизированным, соотношение равно window.outerWidth/window.innerWidth, а когда нет, соотношение, по-видимому, равно (window.outerWidth-16)/window.innerWidth, однако 1-й случай может быть приближен ко 2-му.

Итак, я пришел к следующему ...

Но у этого подхода есть ограничения: например, если вы играете на аккордеоне с окном приложения (быстро увеличиваете и уменьшаете ширину окна), вы получите промежутки между уровнями масштабирования, хотя масштаб не изменился (могут быть externalWidth и innerWidth не точно обновляется в тоже время).

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

И если вы хотите фактор:

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
источник
У меня были проблемы с "window.outerWidth / window.innerWidth", который также дал мне неправильное значение, и это могло быть потому, что я был в iframe. Итак, я использовал родительское окно, и оно дало правильный ответ: window.parent.window.outerWidth / window.parent.window.innerWidth
ylan bellavance
0

У меня есть это решение только для мобильных устройств (протестировано с 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());

});

Если вам нужен уровень масштабирования сразу после сдвига, вам, вероятно, придется установить небольшой тайм-аут из-за задержки рендеринга (но я не уверен, потому что я не тестировал его).

pmrotule
источник
0

Этот ответ основан на комментариях о неправильном возвращении devicePixelRatio на ответ пользователя 1080381.

Я обнаружил, что в некоторых случаях эта команда возвращалась некорректно при работе с рабочим столом, Surface Pro 3 и Surface Pro 4.

Я обнаружил, что он работал на моем рабочем столе, но SP3 и SP4 давали разные цифры друг от друга и на рабочем столе.

Тем не менее, я заметил, что SP3 возвращался с полуторакратным уровнем масштабирования, который я ожидал. Когда я взглянул на настройки дисплея, SP3 на самом деле был установлен на 150% вместо 100% на моем рабочем столе.

Таким образом, решением для комментариев должно быть разделение возвращенного уровня масштабирования на масштаб машины, на которой вы в данный момент находитесь.

Я смог получить масштаб в настройках Windows, выполнив следующие действия:

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

Так что в случае с моим SP3 этот код выглядит при 100% увеличении:

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

Умножение на 100 в исходном ответе user1080381 даст вам увеличение 100 (%).

Кэмерон Уивер
источник
0

В настоящее время он работает, но все равно нужно разделить браузером. Успешно протестирован на Chrome (75) и Safari (11.1) (пока не нашел пути для FF). Он также получает правильное значение масштабирования на дисплее сетчатки, и вычисления запускаются при событии изменения размера.

    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()
    };
  }
Йог
источник
-1

здесь это не меняется!

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

создать простой HTML-файл, нажмите на кнопку. независимо от того, какой уровень масштабирования: он покажет вам ширину 400 пикселей (по крайней мере, с Firefox и ie8)


источник
@tfl: потому что вы установили ширину в стиле inline. Я изменил ваш образец, чтобы показать мое дело (размещено внутри оригинального вопроса).
understack
-1

Это может кому-то помочь, а может и не помочь, но у меня была страница, которую я не мог правильно расположить по центру, независимо от того, какие уловки Css я пробовал, поэтому я написал файл вызова страницы JQuery Center Center:

Возникла проблема с уровнем масштабирования в браузере, при котором страница будет сдвигаться в зависимости от 100%, 125%, 150% и т. Д.

Код ниже находится в файле JQuery с именем centerpage.js.

Со своей страницы мне пришлось сделать ссылку на JQuery и этот файл, чтобы он заработал, хотя на моей главной странице уже была ссылка на 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();
});

Также, если вы хотите центрировать панель:

// 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
источник
-1

Этот вопрос был опубликован как давным-давно, но сегодня, когда я искал один и тот же ответ «Как обнаружить событие увеличения и уменьшения», я не смог найти один ответ, который бы подходил всем браузерам.

Как и сейчас: для Firefox / Chrome / IE8 и IE9 увеличение и уменьшение масштаба вызывает событие window.resize. Это может быть зафиксировано с помощью:

$(window).resize(function() {
//YOUR CODE.
});
Бхуми Сингхал
источник
-1

Обходной путь для FireFox 16+, чтобы найти DPPX (уровень масштабирования) исключительно с помощью 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);
lexasss
источник
Он не работает должным образом в Firefox (52) на MacBook с дисплеем Retina - возвращает 2, когда нет увеличения. Я создал скрипку: 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;
};
али
источник
6
Просьба также объяснить, как работает ваш код. Это будет полезно, если какой-нибудь новичок найдет ваш ответ.
displayName
Я создал скрипку: jsfiddle.net/Terite/5n1bk9do As @AlexeySh. упомянуто, это не работает должным образом на дисплее сетчатки в Chrome (56), Firefox (52). Он также показывает 0 в увеличении Safari (10).
Terite
-1

Проблема заключается в типах используемых мониторов: монитор 4К или стандартный монитор. Chrome на сегодняшний день является самым умным в том, что он может сказать нам, что уровень масштабирования просто использует window.devicePixelRatio, по-видимому, он может сказать, какова плотность пикселей, и сообщать одно и то же число в зависимости от того, что.

Других браузеров не так уж и много. IE и Edge, вероятно, наихудшие, поскольку они по-разному обрабатывают уровни масштабирования. Чтобы получить такой же размер текста на мониторе 4k, вы должны выбрать 200% вместо 100% на стандартном мониторе.

По состоянию на май 2018 года, вот что мне нужно, чтобы определить уровни масштабирования для некоторых из самых популярных браузеров, Chrome, Firefox и IE11. У меня есть это сказать мне, что процент увеличения. Для IE он сообщает 100% даже для 4k мониторов, которые на самом деле на 200%, но размер текста действительно одинаков.

Вот скрипка: https://jsfiddle.net/ae1hdogr/

Если кто-то захочет попробовать другие браузеры и обновить скрипку, сделайте это. Моя главная цель состояла в том, чтобы охватить эти 3 браузера, чтобы определить, используют ли люди коэффициент масштабирования более 100% для использования моего веб-приложения, и отобразить уведомление, предлагающее меньший коэффициент увеличения.

Bill_VA
источник
Safari на Mac Book Pro (экран
Retina
Возвращает 200 на экране сетчатки Chrome & Firefox
OZZIE