Eugene Kostrikov
Eugene Kostrikov

Reputation: 7119

offsetHeight / clientHeight / scrollHeight never change

I'm building a scrolling directive with Angular and see a strange behavior of element heights. They do not change on resize. I went down to the simplest plain JS, but the bug is still here. This fiddle illustrates it http://jsfiddle.net/Y8B86/1/. Try to resize the window and click contents several times and see the console.

function rebuild() {
    var transcluded = document.getElementsByTagName('div')[0];
    scope.scrollHeight = transcluded.scrollHeight;
    scope.offsetHeight = transcluded.offsetHeight;
    scope.clientHeight = transcluded.clientHeight;
}

This function is responsible for reading values. The only difference in Angular is that instead of document.getElementsByTagName i do element.children()[n] to get inner element. Also, the element does not respond to scrolling when window is small enough. ScrollTop does not change.

The question is why height is not updated after window reports resize?

Upvotes: 2

Views: 5677

Answers (2)

JoshSGman
JoshSGman

Reputation: 449

I believe that the problem is that you're expecting scrollHeight, offsetHeight, and clientHeight to change based on the windows size which in fact this is not the case.

The scrollHeight is "a measurement of the height of an element's content including content not visible on the screen due to overflow" (reference).

The offsetHeight is "the height of the element including vertical padding and borders, in pixels, as an integer" (reference).

The clientHeight is "the inner height of an element in pixels, including padding but not the horizontal scrollbar height, border, or margin"(reference).

All three of these are relative to the element for which they are called on. Since it doesn't seem like you have set a relative height for the elements, you will not see any change to their scrollHeight, offsetHeight, or clientHeight. In other words, the elements currently have fixed heights based on the content within them.

You can see this when you make the screen so small that the 'click me' goes across two lines, then your values change.

Upvotes: 5

z.a.
z.a.

Reputation: 2777

you can plug this into your link function in your directive,

angular.element($window).bind('resize', function () {
   rebuild();
});

make sure to inject $window into the directive function, and just call rebuild or another function inside. of course, you should also change the transcluded to the appropriate angularJS form.

Upvotes: 0

Related Questions