diferença entre offsetHeight e clientHeight

154

No dom javascript - qual é a diferença entre offsetHeight e clientHeight de um elemento?

Steve
fonte
6
Aqui está um bom exemplo de demonstração jsfiddle.net/shibualexis/yVhgM/3
GibboK

Respostas:

203

clientHeight :

Retorna a altura da área visível para um objeto, em pixels. O valor contém a altura com o preenchimento, mas não inclui a barra de rolagem, a borda e a margem.

offsetHeight :

Retorna a altura da área visível para um objeto, em pixels. O valor contém a altura com o preenchimento, scrollBar e a borda, mas não inclui a margem.

Portanto, offsetHeightinclui barra de rolagem e borda, clientHeightnão.

Oded
fonte
3
Outra coisa que notei é que o clientHeight é muito mais rápido que o offsetHeight. Tens alguma ideia do porquê?
Disc0dancer #
2
@ disc0dancer - Provavelmente porque o navegador já tem o clientSizeprontamente disponível (afinal, é a janela de exibição), mas precisa calcular offsetHeightdepois de refletir todo o documento?
Oded
Bem, o inspetor do webkit diz que os refluxos também estão presentes em todo o documento, mesmo ao solicitar o clientHeigh.
Disc0dancer #
2
@ disc0dancer - Muito pelo meu palpite. Mas isso é uma coisa de implementação - não tenho certeza de que todos os navegadores são assim.
Oded
83

A resposta de Oded é a teoria. Mas a teoria e a realidade nem sempre são iguais, pelo menos não para os elementos <BODY> ou <HTML>, que podem ser importantes para operações de rolagem em javascript.

A Microsoft tem uma boa imagem no MSDN :

ClientHeight, OffsetHeight, ScrollHeight

Se você possui uma página HTML que mostra uma barra de rolagem vertical, seria de esperar que o elemento <BODY> ou <HTML> tenha um geater ScrollHeight que OffsetHeight, como mostra a imagem. Isso vale para todas as versões mais antigas do Internet Explorer.

Mas isso não acontece no Internet Explorer 11 e no Firefox 36. Pelo menos nesses navegadores, o OffsetHeight é quase o mesmo que o ScrollHeight, que está errado.

E enquanto OffsetHeight pode estar errado, ClientHeight está sempre correto.

Experimente o seguinte código em diferentes navegadores e você verá:

<!DOCTYPE html>
<html>
<body>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<script>
    document.write("Body off: " + document.body.offsetHeight 
             + "<br>Body cli: " + document.body.clientHeight
             + "<br>Html off: " + document.body.parentElement.offsetHeight               
             + "<br>Html cli: " + document.body.parentElement.clientHeight);
</script>
</body>
</html>

Enquanto o Internet Explorer mais antigo é exibido corretamente:

Body off: 1197
Body cli: 1197
Html off: 878
Html cli: 874  

A saída do Firefox e do Internet Explorer 11 é:

Body off: 1260
Body cli: 1260
Html off: 1276   // this is completely wrong
Html cli: 889

o que mostra claramente que offsetHeight está errado aqui. OffsetHeight e ClientHeight devem diferir apenas alguns pixels ou serem iguais.


Observe que ClientHeight e OffsetHeight também podem diferir extremamente para elementos que não são visíveis como, por exemplo, um <FORM>, em que OffsetHeight pode ter o tamanho real do FORM, enquanto ClientHeight pode ser zero.

Elmue
fonte