Como fazer jQuery para não arredondar o valor retornado por .width ()?

94

Procurei e não consegui encontrar isso. Estou tentando obter a largura de um div, mas se tiver um ponto decimal, ele arredonda o número.

Exemplo:

#container{
    background: blue;
    width: 543.5px;
    height: 20px;
    margin: 0;
    padding: 0;
}

Se eu fizer $('#container').width();isso, retornarei 543 em vez de 543,5. Como faço para não arredondar o número e retornar o 543,5 completo (ou qualquer número).

MoDFoX
fonte
2
Por que você tem larguras de pixels decimais? Eles são arredondados de qualquer maneira para números inteiros. Você não pode ter meio pixel.
Moin Zaman
Por que você precisa disso? Sem essa informação, esta pergunta não tem sentido.
Juan Mendes de
2
@JuanMendes No meu caso, em uma tela HiDPI, o Chrome 38 calcula uma largura de janela não inteira. Portanto, se $ .width arredondar para cima, digamos, 1250,6 para 1251 e eu fizer cálculos com base em 1251, tenho problemas. Arredondar para baixo não é tanto um problema.
JKS

Respostas:

196

Use o nativo Element.getBoundingClientRectem vez do estilo do elemento. Foi introduzido no IE4 e é compatível com todos os navegadores:

$("#container")[0].getBoundingClientRect().width

Nota: Para IE8 e versões anteriores, consulte as notas de "Compatibilidade do navegador" nos documentos MDN.

Ross Allen
fonte
9
+1 Se você estiver definindo a largura de outro elemento, certifique-se de alterar sua largura desta forma: $ ("# outro"). Css ("largura", $ ('# container'). Get (0) .getBoundingClientRect ( ) .width + "px"); Se você usar jQuery width (), o valor será arredondado.
lepe
1
De acordo com esta pergunta semelhante, as propriedades widthe heightnão são suportadas em todas as versões do IE, então, em alguns casos, elas precisam ser calculadas antes de serem usadas: stackoverflow.com/questions/11907514/…
flyingL123
Agradável! mesma pergunta para outerWidth (true)? :) pequena observação: `No IE8 e abaixo, o objeto DOMRect retornado por getBoundingClientRect () não possui propriedades de altura e largura. Além disso, propriedades adicionais (incluindo altura e largura) não podem ser adicionadas a esses objetos
DOMRect. »
5
Observe que getBoundingClientRect()calcula as dimensões após aplicar as transformações CSS .
user1620220
Depois de testar, descobri que esse método não funciona para elementos ocultos ( display: none).
Jory Hogeveen
9

Só queria adicionar minha experiência aqui, embora a pergunta seja antiga: o consenso acima parece ser que o arredondamento do jQuery é efetivamente tão bom quanto um cálculo não arredondado - mas não parece ser o caso em algo que tenho feito .

Meu elemento tem uma largura fluida, geralmente, mas o conteúdo muda dinamicamente via AJAX. Antes de mudar o conteúdo, eu bloqueio temporariamente as dimensões do elemento para que meu layout não salte durante a transição. Descobri que usar jQuery assim:

$element.width($element.width());

está causando alguma graça, como a existência de diferenças subpixel entre a largura real e a largura calculada. (Especificamente, verei uma palavra saltar de uma linha de texto para outra, indicando que a largura foi alterada, não apenas bloqueada.) De outra pergunta - Obtendo a largura real de ponto flutuante de um elemento - descobri que window.getComputedStyle(element).widthretornará um cálculo não arredondado. Então mudei o código acima para algo como

var e = document.getElementById('element');
$('#element').width(window.getComputedStyle(e).width);

E com ESSE código - sem pulos engraçados! Essa experiência parece sugerir que o valor não arredondado realmente importa para o navegador, certo? (No meu caso, Chrome versão 26.0.1410.65.)

Davidtheclark
fonte
A documentação atual para .css () do jQuery aponta que getComputedStyle () é chamado runtimeStyle () i IE, e afirma que uma das vantagens de .css () é essa interface unificada.
Norwebian
9

A resposta de Ross Allen é um bom ponto de partida, mas usando getBoundingClientRect (). Width também incluirá o preenchimento e a largura da borda, o que não é o caso da função de largura do jquery :

O objeto TextRectangle retornado inclui o preenchimento, a barra de rolagem e a borda, mas exclui a margem. No Internet Explorer, as coordenadas do retângulo delimitador incluem as bordas superior e esquerda da área do cliente.

Se sua intenção é obter o widthvalor com precisão, você terá que remover o preenchimento e a borda como este:

var a = $("#container");
var width = a[0].getBoundingClientRect().width;

//Remove the padding width (assumming padding are px values)
width -= (parseInt(a.css("padding-left")) + parseInt(a.css("padding-right")));

//Remove the border width
width -= (a.outerWidth(false) - a.innerWidth());
The_Black_Smurf
fonte
Você não o deve .replace("px", "")como parseIntdeve remover isso para você.
Steve Schrab de
Sendo esta questão toda sobre a prevenção de arredondamento, estou confuso com a suposição explícita aqui de que arredondamento é bom para os valores de preenchimento. Por que você trataria isso de forma diferente dos valores de largura ?! Use parseFloat()talvez?
phils,
Da mesma forma, por innerWidth()ser parte do problema original, temo que o cálculo da largura da borda aqui também esteja trabalhando em valores arredondados.
phils,
2

Você pode usar getComputedStylepara isso:

parseFloat(window.getComputedStyle($('#container').get(0)).width)
Anton Chukanov
fonte
-1

Use o seguinte para obter uma largura precisa:

var htmlElement=$('class or id');
var temp=htmlElement[0].style.width;
Ali Hasan
fonte
por que você quer que o jquery obtenha sua largura computada se você realmente a configurou e a disponibilizou emstyle.width
user151496