Як виявити рівень масштабування сторінки у всіх сучасних браузерах?


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>

1
В основному я хочу знати розмір DIV при 100% масштабі.
understack

4
В основному немає можливості виявити масштаб у 2019 році : я протестував усі наведені нижче рішення на Chrome 78 на Mac Catalina, і жодне з них не працювало.
collimarco

Відповіді:


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 : вимірюйте бажаний розмір значка за допомогою -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 говорить про помилку; InternalWidth повинна бути CSS px). Ми використовуємо позицію: фіксований елемент, щоб отримати ширину вікна перегляду, включаючи простір, де знаходяться смуги прокрутки ; document.documentElement.clientWidth виключає цю ширину. Це порушено з колись у 2011 році; Я вже не знаю, як досягти рівня збільшення в Opera.
  • Інше : флеш-рішення від Себастьяна
  • Ненадійний: слухати події миші та вимірювати зміни в екраніX / зміна 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>

1
Дуже приємна робота, хоча це не працює для мене в IE 8.0.7601.17514 (останнє). Будь-який шанс завершити все це в одній функції getZoom (), яка працює в усіх браузерах? Можливо, також випустити як плагін jQuery? Приємна робота знову.
ripper234

1
@yonran чудовий плагін !, але він не працює в IE9, він повинен бути zoom: screen.deviceXDPI / screen.logicalXDPI,замістьzoom: screen.systemXDPI / screen.logicalXDPI,
Daniel

1
@RobW, коли я вперше написав це для Firefox 4, Firefox не мав matchMedia. Пол Ірланд також написав подібний полімет MatchMedia, який є частиною Modernizr .
йонран

7
Гарні новини, всі! Вони, нарешті, зробили це! API Vieport! Chromeestatus.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 
});

1
Працює ідеально, також на мобільних пристроях. Також досить цікаво побачити, які мобільні пристрої є чим devicePixelRatio. Це також значно допомогло мені переключити fixedелемент на елемент, розташований на absoluteлі, коли відбувається подія масштабування або коли devicePixelRatioзмінюється первісне значення . Ідеально! Дякую!!
lowtechsun

12
Не працює, як очікувалося: він повертає 200 в Chrome на MacBook із сітківкою, коли браузер не збільшується.
Terite

19
Веб-браузери з підтримкою високих екранів DPI не дадуть очікуваного результату при використанні такого дисплея, а також Safari незалежно від відображення.
Фредрік C

Для всіх, хто хвилює, в IE це працює лише на IE11 (він поверне NaN на IE10 або нижче)
scunliffe

3
Math.round(window.devicePixelRatio * 100)працює в Chrome, IE, Edge та Firefox. Сафарі на iMac завжди повертає 200.
Супер Джейд

45

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

Використовуючи window.innerWidthта window.outerWidthпрацював. Чомусь у Chrome зовнішня ширина вимірюється в пікселях екрана, а внутрішня - у пікселях 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";
}

1
Дуже хороший. І якщо вам потрібно лише знати, чи він збільшується чи ні в Chrome:isZoomed = (screenCssPixelRatio < .98 || screenCssPixelRatio > 1.02)
Brent Faust

1
Що ж, window.outerWidth також змінюється із збільшенням. Крім того, не для кожної ОС ширина рамки вікна становить 8 пікселів (навіть в одній ОС дизайн може змінюватись). Однак я б запропонував викласти 16, а не 8, оскільки у вас є рамки вікна двічі. Також деякі веб-переглядачі мають рамки вікна візуалізації (наприклад, FF), а деякі не (Safari), але навіть це залежить від того, для якої ОС ви використовуєте браузер (наприклад, у Safari є межа з Windows). Резервне копіювання початкової внутрішньої ширини (наприклад, на завантаження сторінки) та використання її для порівняння працює краще, але тільки якщо інціональний масштаб був 100% ...
СТЕН

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, схоже, має таку саму проблему на робочому столі, коли висота екрана відрегульована на пристрої перегляду, PixelRatio, який досить закручений.
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, які також були одинарними лініями, я зміг виявити масштабування переважної більшості браузерів, що вражали наш додаток лише кількома рядками коду.


4
Чи можете ви надати код, як виявити фактичне збільшення за допомогою медіа-запиту?
ТН.

Спробуйте використовувати просто "(ширина: <X> px) і (висота: <Y> px)", де <X> і <Y> - window.innerWidth і window.innerHeight відповідно. Він працює навіть при дуже невеликих масштабах. Працює і в Safari.
макс

@max Чи можете ви надати JSFIddle або зразок коду, як це виглядає разом?
lowtechsun

Завжди повідомляє правду на пристроях сітківки, таких як macbook pro.
Меттью Сандерс

codepen.io/anon/pen/LgrGjJ показує двійковий пошук з медіа-запитами, але це те саме, що і запити devicePixelRatio: він враховує масштабування дисплея.
ZachB

11
zoom = ( window.outerWidth - 10 ) / window.innerWidth

Це все, що вам потрібно.


Чому віднімати 10з outerWidth?
callum

Напевно, для смуги прокрутки. Кожна смуга прокрутки теж відрізняється, як і в 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, застосовується масштабування. Різниця між ними говорить про величину збільшення.

Примітка: Розрахунки відстані виконуйте лише рідко, наприклад, коли ви можете пробити нову подію миші, далеко не попередню.

Обмеження: передбачається, що користувач хоч трохи перемістить мишу, і масштабування не пізнається до цього часу.


1
Я створив скрипку: jsfiddle.net/Terite/9b6ko854 з "далеко один від одного", що означає 100 пікселів. На жаль, він працює нестабільно на Firefox (52) на MacBook із сітківкою дисплея. Також слід зазначити, що в Chrome, Firefox та IE11 (в масштабі 125%, що за замовчуванням тоді, за замовчуванням) виявлено масштаб інтерфейсу 125% у масштабі браузера.
Terite

Ваша скрипка працює для мене, протестована в Linux з Firefox та Chrome :)
user1191311

Дисплеї сітківки додають ще один рівень складності, оскільки вони повідомляють про розміри пікселів неправильно, серед іншого.
користувач1191311

5

Ви можете використовувати API Visual Viewport :

window.visualViewport.scale;

Він стандартний і працює як на робочому столі, так і на мобільному: підтримка браузера .


Здається зручно, але він все ще відключений за замовчуванням на робочому столі Firefox і не працює в Internet Explorer станом на 5/31/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 масштабування не існує, тому перевіряти збільшення не потрібно.


1
Цікаво. Для мене це завжди показує 80% масштабу ... Я вважаю, це тому, що у мене великі налаштування шрифтів на рівні Windows 7 (пошук "розміру шрифту" на панелі управління). Це краще, ніж рішення IE8 у відповіді @ yonran, яке для мене зовсім не спрацювало. jsbin.com/obowof
ripper234

Я отримую 101%, коли зум встановлений на 100%.
Аллен Уоллес

я також. використовуйте 0,4999 замість 0,9
yan bellavance

ieZoomLevel = ((screen.deviceXDPI / screen.systemXDPI) * 100 + 0.4999) .toFixed ();
yan bellavance

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

Це для мене чудово працювало у веб-браузерах (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;

5
document.widthповертається невизначено
Адам

Завжди повертає справжнє незалежно від масштабування (2017, feb, відображення сітківки).
Tiberiu-Ionuț Stan

3

В основному, ми маємо:

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

цього повинно вистачити для нормального UX. Якщо вам потрібно виявити рівень масштабування, це може бути ознакою поганого дизайну інтерфейсу.

Піт-зум важче відстежувати і наразі не розглядається.


1
window.devicePixelRatio - це хороша відповідь, яка працює в останній версії основних браузерів - Chrome, Safari, FF, Edge, IE
DShultz

@kirilloid Ви знайшли щось, що можна було б використати для надійного пошуку "рівня масштабу" в Safari?
onassar

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. Зараз вони просто іншого розміру на екрані. Це сенс повного збільшення сторінки.

Що ви хочете зробити в браузері на пристрої 192dpi, який зазвичай відображає чотири пікселі пристрою на кожен піксель зображення? При 50-кратному масштабі цей пристрій тепер відображає один піксель зображення в одному пікселі пристрою.


@Neil: як я можу отримати розміри "CSS-пікселів"?
understack

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
Працює лише тоді, коли вікно браузера має повну ширину екрана.
тенбіти

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, однак до першого випадку можна звернутися до другого.

Тож я прийшов до наступного ...

Але такий підхід має обмеження: наприклад, якщо ви граєте на гармошці з вікном програми (швидко збільшуйте та зменшуйте ширину вікна), ви отримаєте прогалини між рівнями масштабування, хоча зум не змінився (можливо, зовнішня ширина і внутрішня ширина не є точно оновлено в той же час).

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

У мене виникли проблеми з "window.outerWidth / window.innerWidth", що дало мені неправильне значення, і це могло бути тому, що я потрапив у рамку iframe. Тож, що я зробив, я використав батьківське вікно, і воно дало правильну відповідь: window.parent.window.outerWidth / window.parent.window.innerWidth
Ян Беллаванс

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

});

Якщо ви хочете, щоб рівень масштабування був досягнутий відразу після переміщення, то, ймовірно, вам доведеться встановити невеликий тайм-аут через затримку візуалізації (але я не впевнений, тому що я його не перевіряв).


0

Ця відповідь ґрунтується на коментарях щодо пристроюPixelRatio, який неправильно повертається на відповідь користувача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 в оригінальній відповіді користувача 1080381 тоді дало б масштаб 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:

Проблема виникла із рівнем масштабування веб-переглядача, сторінка змістилася б на основі 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);
    }
}

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

Це не працює так, як очікувалося в Firefox (52) на MacBook із відображенням сітківки - повертає 2, коли не збільшується. Я створив загадку
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

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

Інших браузерів, не так багато. IE і Edge - це, мабуть, найгірше, оскільки вони обробляють рівні масштабування набагато по-різному. Щоб отримати однаковий розмір тексту на моніторі 4k, потрібно вибрати 200%, а не 100% на стандартному моніторі.

Станом на травень 2018 року, ось що мені потрібно виявити масштаби для кількох найпопулярніших браузерів, Chrome, Firefox та IE11. Я маю це сказати мені, який відсоток збільшення. Для IE він повідомляє 100% навіть для 4-х моніторів, які насправді на 200%, але розмір тексту дійсно той самий.

Ось загадка: https://jsfiddle.net/ae1hdogr/

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


Safari на Mac Book Pro (сітчастий екран) повертає 0, Chrome на екрані сітківки повертається правильно, здається, 100, 90 і т.д.
OZZIE

Повертає 200 на екрані сітківки Chrome & Firefox
OZZIE
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.