Como detectar o nível de zoom da página em todos os navegadores modernos?

310
  1. Como posso detectar o nível de zoom da página em todos os navegadores modernos? Embora este tópico explique como fazê-lo no IE7 e IE8, não consigo encontrar uma boa solução entre navegadores.

  2. O Firefox armazena o nível de zoom da página para acesso futuro. No carregamento da primeira página, seria possível obter o nível de zoom? Em algum lugar que li, funciona quando ocorre uma alteração de zoom após o carregamento da página.

  3. Existe uma maneira de interceptar o 'zoom'evento?

Preciso disso porque alguns dos meus cálculos são baseados em pixels e podem variar quando ampliados.


Amostra modificada fornecida por @tfl

Esta página alerta diferentes valores de altura quando ampliada. [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>
subestimar
fonte
1
Basicamente, quero saber a dimensão de um DIV com 100% de zoom.
understack
4
Basicamente, não há como detectar o zoom em 2019 : testei todas as soluções abaixo no Chrome 78 no Mac Catalina e nenhuma delas funcionou.
Collimarco 27/11/19

Respostas:

274

Agora é uma bagunça ainda maior do que era quando essa pergunta foi feita pela primeira vez. Da leitura de todas as respostas e postagens do blog que pude encontrar, aqui está um resumo. Também configurei esta página para testar todos esses métodos de medir o nível de zoom .

Edit (12/12/2011): adicionei um projeto que pode ser clonado: https://github.com/tombigel/detect-zoom

  • IE8 : screen.deviceXDPI / screen.logicalXDPI(ou, para o nível de zoom em relação ao zoom padrão screen.systemXDPI / screen.logicalXDPI)
  • IE7 : var body = document.body,r = body.getBoundingClientRect(); return (r.left-r.right)/body.offsetWidth;(graças a este exemplo ou a esta resposta )
  • SOMENTE FF3.5 : screen.width/ largura da tela de consulta de mídia (veja abaixo) (aproveita o fato de screen.widthusar pixels do dispositivo, mas a largura do MQ usar pixels CSS - graças às larguras do modo Quirks )
  • FF3.6 : nenhum método conhecido
  • FF4 + : mídia consulta pesquisa binária (veja abaixo)
  • WebKit : https://www.chromestatus.com/feature/5737866978131968 (obrigado a Teo nos comentários)
  • WebKit : mede o tamanho preferido de uma div com -webkit-text-size-adjust:none.
  • WebKit : (quebrado desde r72591 ) document.width / jQuery(document).width()(graças a Dirk van Oosterbosch acima ). Para obter uma proporção em termos de pixels do dispositivo (em vez de em relação ao zoom padrão), multiplique por window.devicePixelRatio.
  • WebKit antigo? (não verificado): parseInt(getComputedStyle(document.documentElement,null).width) / document.documentElement.clientWidth( desta resposta )
  • Opera : document.documentElement.offsetWidth/ largura de uma position:fixed; width:100%div. daqui ( a tabela de larguras do Quirksmode diz que é um bug; innerWidth deve ser px de CSS). Usamos a posição: elemento fixo para obter a largura da janela de visualização, incluindo o espaço onde estão as barras de rolagem ; document.documentElement.clientWidth exclui essa largura. Isso está quebrado desde que em 2011; Não sei mais como obter o nível de zoom no Opera.
  • Outros : solução Flash de Sebastian
  • Não confiável: ouça os eventos do mouse e meça as alterações no screenX / as alterações no clientX

Aqui está uma pesquisa binária do Firefox 4, pois não conheço nenhuma variável em que ela esteja exposta:

<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
fonte
1
Um trabalho muito bom, embora isso não funcione para mim no IE 8.0.7601.17514 (mais recente). Alguma chance de encerrar tudo isso em uma única função getZoom () que funciona em todos os navegadores? Talvez também seja lançado como um plugin jQuery? Bom trabalho novamente.
usar o seguinte código
1
@yonran ótimo plugin !, Mas ele não funciona no IE9 deveria ser zoom: screen.deviceXDPI / screen.logicalXDPI,, em vez dezoom: screen.systemXDPI / screen.logicalXDPI,
Daniel
1
@ RobW, quando escrevi isso para o Firefox 4, o Firefox não tinha matchMedia. Paul Irish também escreveu um polyfill matchMedia semelhante que faz parte do Modernizr .
precisa saber é
7
Boas notícias, pessoal! Eles finalmente fizeram isso! API do Vieport! chromestatus.com/feature/5737866978131968 Eu testo, ótimas coisas!
Teo
3
A API da Viewport funciona apenas para zoom de pinça; se você aumentar o zoom na área de trabalho, a escala é 1. @ Jason T Featheringham, existem outras razões além da "discriminação" para querer saber o nível de zoom. O zoom é definido em todas as páginas de um domínio, mas você pode lidar com isso de maneira diferente em uma página de jogo ou em um pop-up de extensão do que em uma página de ajuda.
Pudica 27/03
61

Podes tentar

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

Isso fornecerá o nível percentual de zoom do navegador em telas que não sejam da retina. Para exibições altas de DPI / retina, produziria valores diferentes (por exemplo, 200 para Chrome e Safari, 140 para Firefox).

Para capturar um evento de zoom, você pode usar

$(window).resize(function() { 
// your code 
});
user1080381
fonte
1
Funciona perfeitamente, também em dispositivos móveis. Também é bastante interessante ver quais dispositivos móveis têm o quê devicePixelRatio. Isso também me ajudou muito a mudar um fixedelemento para um elemento absoluteposicionado quando o evento de zoom ocorre ou quando o valor inicial das devicePixelRatioalterações. Perfeito! Obrigado!!
lowtechsun
12
Não funciona conforme o esperado: ele retorna 200 no Chrome no MacBook com retina quando o navegador não aumenta o zoom.
Terite 22/03
19
Navegadores com suporte para telas de alto DPI não fornecerão o resultado esperado ao usar essa tela, nem o Safari, independentemente da tela.
Fredrik C
Apenas para qualquer um que se preocupa, no IE isso só funciona no IE11 (ele retornará NaN no IE10 ou abaixo)
scunliffe
3
Math.round(window.devicePixelRatio * 100)funciona no Chrome, IE, Edge e Firefox. Safari no iMac sempre retorna 200.
Super Jade
45

Para mim, para o Chrome / Webkit, document.width / jQuery(document).width()não funcionou. Quando reduzi a janela e ampliei o zoom no site, de forma que as barras de rolagem horizontais aparecessem, document.width / jQuery(document).width()não era igual a 1 no zoom padrão. Isto é porquedocument.width inclui parte do documento fora da janela de exibição.

Usando window.innerWidthe window.outerWidthtrabalhado. Por alguma razão, no Chrome, a largura externa é medida em pixels da tela e a largura interna é medida em pixels 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
fonte
1
Muito agradável. E se você só precisa saber se está com zoom ou não no Chrome:isZoomed = (screenCssPixelRatio < .98 || screenCssPixelRatio > 1.02)
Brent Faust
1
Bem, window.outerWidth também é alterado com o zoom. Além disso, nem em todos os sistemas operacionais, a largura da borda da janela é de 8 pixels (mesmo no mesmo sistema operacional, o design pode variar). No entanto, eu sugeriria subtrair 16, não 8, já que você tem as bordas da janela duas vezes. Além disso, alguns navegadores têm uma borda na janela de renderização real (como FF) e outros não (Safari) - mas mesmo isso depende de qual SO você usa o navegador (por exemplo, o Safari tem uma borda no Windows). Fazer o backup do innerWidth inicial (por exemplo, na página de carga) e usá-lo para comparar obras melhor, mas somente se zoom initional foi de 100% ...
Stane
1
Resultados 0, não importa o que para mim (2017, fevereiro).
Tiberiu-Ionuț Stan
1
switchdeclaração pode ser melhor do que muitas declarações if else.
Edric
Ele não funciona: apenas testado em Chrome para Mac e ele sempre retorna a mesma proporção, independentemente do nível de zoom
collimarco
16

Eu e meu colega de trabalho usamos o script em https://github.com/tombigel/detect-zoom . Além disso, também criamos dinamicamente um elemento svg e verificamos sua propriedade currentScale. Funciona muito bem no Chrome e provavelmente na maioria dos navegadores. No FF, o recurso "somente texto de zoom" deve ser desativado. O SVG é suportado na maioria dos navegadores. No momento da redação deste artigo, testado no IE10, FF19 e ​​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);
Jay
fonte
Agora, esse método sempre relata svg.currentScale = 1 no Firefox 29. Provavelmente porque eles redimensionam as figuras da tela inteira com base no zoom, o que é um erro . O IE11 parece ter o mesmo problema na área de trabalho, com a altura da tela ajustada para o dispositivo viewportPixelRatio, que está completamente estragado.
Hexalys
11

Achei este artigo extremamente útil. Um enorme obrigado a yonran. Eu queria transmitir um aprendizado adicional que encontrei ao implementar algumas das técnicas que ele forneceu. No FF6 e no Chrome 9, foi adicionado suporte para consultas de mídia do JS, o que pode simplificar bastante a abordagem de consulta de mídia necessária para determinar o zoom no FF. Veja os documentos no MDN aqui . Para meus propósitos, eu só precisava detectar se o navegador estava com mais ou menos zoom, não era necessário o fator de zoom real. Consegui obter minha resposta com uma linha de JavaScript:

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

Combinando isso com as soluções IE8 + e Webkit, que também eram linhas únicas, consegui detectar o zoom na grande maioria dos navegadores que acessam nosso aplicativo com apenas algumas linhas de código.

brianh
fonte
4
Você poderia fornecer um código como detectar o zoom real usando a consulta de mídia?
TN.
Tente usar apenas "(largura: <X> px) e (altura: <Y> px)", onde <X> e <Y> são window.innerWidth e window.innerHeight, respectivamente. Funciona mesmo para pequenas quantidades de zoom. Também funciona no Safari.
máximo
@max Você pode fornecer um JSFIddle ou um código de exemplo de como isso se parece?
lowtechsun
Sempre relata verdadeiros em dispositivos retina, como o macbook pro.
Matthew Sanders
codepen.io/anon/pen/LgrGjJ mostra uma pesquisa binária com consultas de mídia, mas é o mesmo que consulta devicePixelRatio: leva em consideração o dimensionamento da exibição.
ZachB 19/10
11
zoom = ( window.outerWidth - 10 ) / window.innerWidth

É tudo o que você precisa.

Alex von Thorn
fonte
Por subtrair 10a partir outerWidth?
Callum #
Provavelmente para a barra de rolagem. Cada barra de rolagem também é diferente, como no iOS é muito menor. Além disso, esta solução parece ser cromo única
Sarah
1
Não funciona se o usuário tiver uma barra lateral como favoritos no FF
Gerrit Sedlaczek
7

Eu tenho uma solução para isso a partir de janeiro de 2016. Testado trabalhando nos navegadores Chrome, Firefox e MS Edge.

O princípio é o seguinte. Colete 2 pontos MouseEvent que estão distantes. Cada evento do mouse vem com coordenadas de tela e documento. Meça a distância entre os 2 pontos nos dois sistemas de coordenadas. Embora existam deslocamentos fixos variáveis ​​entre os sistemas de coordenadas devido à mobília do navegador, a distância entre os pontos deve ser idêntica se a página não for ampliada. A razão para especificar "distantes" (eu coloquei isso como 12 pixels) é para que pequenas alterações de zoom (por exemplo, 90% ou 110%) sejam detectáveis.

Referência: https://developer.mozilla.org/en/docs/Web/Events/mousemove

Passos:

  1. Adicionar um ouvinte de movimentação do mouse

    window.addEventListener("mousemove", function(event) {
        // handle event
    });
  2. Capture 4 medidas dos eventos do mouse:

    event.clientX, event.clientY, event.screenX, event.screenY
  3. Meça a distância d_c entre os 2 pontos no sistema do cliente

  4. Meça a distância d_s entre os 2 pontos no sistema de tela

  5. Se d_c! = D_s, o zoom será aplicado. A diferença entre os dois indica a quantidade de zoom.

Nota: Apenas faça os cálculos de distância raramente, por exemplo, quando você pode experimentar um novo evento de mouse que está longe do anterior.

Limitações: pressupõe que o usuário mova o mouse pelo menos um pouco e o zoom não é conhecido até esse momento.

user1191311
fonte
1
Eu criei um violino: jsfiddle.net/Terite/9b6ko854 com "distante", com o significado de 100 pixels. Infelizmente, ele funciona instável no Firefox (52) no MacBook com tela retina. Também deve ser observado que o zoom da interface do Windows 7 125% é detectado no Chrome, Firefox e IE11 (no zoom 125%, que é o padrão então) como um zoom do navegador.
Terite 22/03
Suas obras violino para mim, testado em Linux com o Firefox e Chrome :)
user1191311
As telas de retina adicionam outro nível de dificuldade, porque relatam os tamanhos de pixel incorretamente, entre outras coisas.
user1191311
5

Você pode usar a API do Visual Viewport :

window.visualViewport.scale;

É padrão e funciona tanto em computadores quanto em dispositivos móveis: suporte ao navegador .

collimarco
fonte
Parece útil, mas ainda está desativado por padrão na área de trabalho do Firefox e não funciona no Internet Explorer a partir de 31/5/20.
derekbaker783
3

No Internet Explorer 7, 8 e 9, isso funciona:

function getZoom() {
    var screen;

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

O "+0.9" é adicionado para evitar erros de arredondamento (caso contrário, você obteria 104% e 109% quando o zoom do navegador estiver definido para 105% e 110%, respectivamente).

No IE6, o zoom não existe; portanto, não é necessário verificar o zoom.

apertar
fonte
1
Interessante. Para mim, ele sempre mostra 80% do zoom ... Acredito que isso ocorra porque tenho fontes grandes configuradas no nível do Windows 7 (pesquise "tamanho da fonte" no painel de controle). É melhor que a solução IE8 na resposta do @ yonran que não funcionou para mim. jsbin.com/obowof
ripper234 09/10
Estou recebendo 101% quando o zoom está definido como 100%.
Allen Wallace
eu também. usar 0,4999 em vez de 0,9
yan Bellavance
ieZoomLevel = ((screen.deviceXDPI / screen.systemXDPI) * 100 + 0.4999) .toFixed ();
yan Bellavance
3

O que eu vim com é:

1) Faça um position:fixed <div>com width:100%( id = zoomdiv )

2) quando a página carrega:

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

E funcionou para mim ctrl+e ctrl-amplia.

ou posso adicionar a linha a um $(window).onresize()evento para obter o nível de zoom ativo


Código:

<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: este é o meu primeiro post, perdoe qualquer erro

Abhishek Borar
fonte
3
Infelizmente, isso só funcionará se o usuário tiver o navegador maximizado ( screen.availWidthinforma a largura da tela em pixels da tela, não na janela do navegador).
Bailey Parker
3

Isso funcionou muito bem para mim em navegadores baseados em 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;
}

Parece não funcionar no Firefox.

Isso também funciona no WebKit:

var zoomLevel = document.width / document.body.clientWidth;
rudolfrck
fonte
5
document.widthretorna indefinido
Adam
Sempre retorna verdadeiro, independentemente do zoom (2017, fevereiro, exibição de retina).
Tiberiu-Ionuț Stan
3

Basicamente, temos:

  • window.devicePixelRatioque leva em consideração o zoom no nível do navegador * e a densidade do zoom / pixel do sistema.
    * - no nível de zoom do Mac / Safari não é levado em consideração
  • consultas de mídia
  • vw/ vhUnidades CSS
  • resize evento, que é acionado após a alteração do nível de zoom, causa mudanças efetivas no tamanho das janelas

isso deve ser suficiente para UX normal . Se você precisar detectar o nível de zoom, isso pode ser um sinal de mau design da interface do usuário.

O zoom de inclinação é mais difícil de rastrear e não é considerado atualmente.

kirilloid
fonte
1
window.devicePixelRatio é uma boa resposta que funciona em versões mais recentes dos principais navegadores - Chrome, Safari, FF, EDGE, IE
DShultz
@kirilloid, você encontrou algo que pudesse ser usado para encontrar com segurança o "nível de zoom" no Safari?
Onassar 9/05/19
1

Seus cálculos ainda são baseados em vários pixels CSS. Eles são apenas um tamanho diferente na tela agora. Esse é o ponto do zoom da página inteira.

O que você gostaria que acontecesse em um navegador em um dispositivo de 192 dpi que, portanto, normalmente exibia quatro pixels de dispositivo para cada pixel em uma imagem? Com 50% de zoom, este dispositivo agora exibe um pixel de imagem em um pixel.

Neil
fonte
@ Neil: como posso obter dimensões 'pixels em CSS'?
understack
O padrão é CSS para pontos, mas é claro que você pode especificar pixels usando o modificador de dimensão px. Quanto às propriedades do elemento recuperadas em JavaScript, elas já devem estar em pixels CSS. Portanto, se você especificar a largura de um <div> como 100px, é isso que você receberá do JavaScript, qualquer que seja o nível de zoom.
214 Neil
1

No Chrome

var ratio = (screen.availWidth / document.documentElement.clientWidth);
var zoomLevel = Number(ratio.toFixed(1).replace(".", "") + "0");
Nicolas Giszpenc
fonte
1
Funciona apenas quando a janela do navegador tem toda a largura da tela.
Dezbits
0

Não testou isso no IE, mas se você criar um elemento elemcom

min-width: 100%

então

window.document.width / elem.clientWidth

fornece o nível de zoom do navegador (incluindo o document.body.style.zoomfator).

Dirk van Oosterbosch
fonte
Testado isso, mas o zoom em não parece aumentar elem.clientWidth
Tom
0

Isso é para o Chrome , na sequência da resposta do usuário800583 ...

Passei algumas horas nesse problema e não encontrei uma abordagem melhor, mas:

  • Existem 16 'zoomLevel' e não 10
  • Quando o Chrome está em tela cheia / maximizado, a proporção é window.outerWidth/window.innerWidth, e quando não é, a proporção parece ser (window.outerWidth-16)/window.innerWidth, no entanto, o primeiro caso pode ser abordado pelo segundo.

Então eu vim para o seguinte ...

Mas essa abordagem tem limitações: por exemplo, se você tocar acordeão com a janela do aplicativo (aumentar e reduzir rapidamente a largura da janela), haverá intervalos entre os níveis de zoom, embora o zoom não tenha sido alterado (pode ser a largura externa e a largura interna não são exatamente atualizado ao mesmo tempo).

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

E se você quiser o fator:

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
fonte
Eu tive problemas com "window.outerWidth / window.innerWidth", fornecendo o valor errado também e isso pode ter acontecido porque eu estava em um iframe. Então, o que eu fiz é que eu usei a janela pai e deu a resposta correta: window.parent.window.outerWidth / window.parent.window.innerWidth
yan Bellavance
0

Eu tenho esta solução apenas para celular (testada com 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());

});

Se você quiser o nível de zoom logo após a movimentação da pitada, provavelmente terá que definir um tempo limite devido ao atraso na renderização (mas não tenho certeza porque não o testei).

pmrotule
fonte
0

Esta resposta é baseada em comentários sobre o devicePixelRatio retornando incorretamente na resposta do usuário1080381.

Descobri que esse comando também estava retornando incorretamente em alguns casos ao trabalhar com uma área de trabalho, o Surface Pro 3 e o Surface Pro 4.

O que descobri é que funcionava na minha área de trabalho, mas o SP3 e o SP4 estavam fornecendo números diferentes um do outro e da área de trabalho.

Percebi, porém, que o SP3 estava voltando com uma vez e meia o nível de zoom que eu esperava. Quando dei uma olhada nas configurações de vídeo, o SP3 estava realmente definido para 150% em vez dos 100% que eu tinha na minha área de trabalho.

Portanto, a solução para os comentários deve ser dividir o nível de zoom retornado pela escala da máquina em que você está atualmente.

Consegui obter a escala nas configurações do Windows, fazendo o seguinte:

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

Portanto, no caso do meu SP3, é assim que esse código parece com 100% de zoom:

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

Multiplicando os 100 na resposta original do usuário1080381, você obteria um zoom de 100 (%).

Cameron Weaver
fonte
0

Tê-lo funcionando atualmente, no entanto ainda precisa separar pelo navegador. Testado com sucesso no Chrome (75) e Safari (11.1) (ainda não encontrou caminho para o FF). Ele também obtém o valor de zoom correto na exibição da retina e os cálculos são acionados no evento de redimensionamento.

    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()
    };
  }
Yogi
fonte
-1

aqui isso não muda !:

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

Para criar um arquivo html simples, clique no botão independentemente do nível de zoom: ele mostrará a largura de 400px (pelo menos no Firefox e ie8)


fonte
@tfl: é porque você corrigiu a largura no estilo embutido. Modifiquei sua amostra para mostrar meu caso (publicado na pergunta original).
understack
-1

Isso pode ou não ajudar ninguém, mas eu tinha uma página que não conseguia acessar corretamente, não importando quais truques de Css eu tentei, então escrevi um arquivo de chamada JQuery na Central de Página:

O problema ocorreu com o nível de zoom do navegador; a página mudaria com base em se você fosse 100%, 125%, 150% etc.

O código abaixo está em um arquivo JQuery chamado centerpage.js.

Na minha página, tive que vincular ao JQuery e esse arquivo para fazê-lo funcionar, mesmo que minha página mestre já tivesse um link para o 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();
});

Além disso, se você deseja centralizar um painel:

// 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
fonte
-1

Esta pergunta foi publicada há muito tempo, mas hoje, quando eu estava procurando a mesma resposta "Como detectar eventos de aumento e redução de zoom", não consegui encontrar uma resposta adequada para todos os navegadores.

Como agora: no Firefox / Chrome / IE8 e IE9, o zoom in e out dispara um evento window.resize. Isso pode ser capturado usando:

$(window).resize(function() {
//YOUR CODE.
});
Bhumi Singhal
fonte
-1

Uma solução alternativa para o FireFox 16+ encontrar o DPPX (nível de zoom) apenas com 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
fonte
Ele não funciona como esperado no Firefox (52) no MacBook com tela retina - retorna 2 quando não está no zoom. Eu criei um violino: jsfiddle.net/Terite/wadkh3ea
Terite 22/03
-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;
};
todos
fonte
6
Por favor, também explique como seu código funciona. Isso será útil se algum novato encontrar sua resposta.
displayName
Criei um violino: jsfiddle.net/Terite/5n1bk9do As @AlexeySh. mencionado, ele não funciona conforme o esperado na exibição da retina no Chrome (56), Firefox (52). Também mostra 0 de zoom no Safari (10).
Terite 22/03
-1

O problema está nos tipos de monitor usados, um monitor 4K e um monitor padrão. O Chrome é de longe o mais inteligente em nos dizer qual é o nível de zoom usandowindow.devicePixelRatio , aparentemente ele pode dizer qual é a densidade de pixels e relata o mesmo número para importar o que for.

Outros navegadores, nem tanto. O IE e o Edge são provavelmente os piores, pois lidam com os níveis de zoom de maneira muito diferente. Para obter o mesmo tamanho de texto em um monitor de 4k, é necessário selecionar 200%, em vez de 100% em um monitor padrão.

Em maio de 2018, eis o que tenho para detectar os níveis de zoom em alguns dos navegadores mais populares, Chrome, Firefox e IE11. Eu tenho que me dizer qual é a porcentagem de zoom. Para o IE, ele relata 100%, mesmo para monitores 4K que estão realmente em 200%, mas o tamanho do texto é realmente o mesmo.

Aqui está um violino: https://jsfiddle.net/ae1hdogr/

Se alguém quiser dar uma facada em outros navegadores e atualizar o violino, faça isso. Meu principal objetivo era cobrir esses três navegadores para detectar se as pessoas estavam usando um fator de zoom maior que 100% para usar meu aplicativo da web e exibir um aviso sugerindo um fator menor de zoom.

Bill_VA
fonte
Safari no Mac Book Pro (tela retina) retorna 0, o Chrome em retornos não tela retina corretamente parece 100, 90 etc
OZZIE
Retorna 200 na tela retina do Chrome e Firefox
OZZIE