Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect Document Height Change

I'm trying to detect when my document height changes. Once it does, I need to run a few functions to help organize my page layout.

I'm not looking for window.onresize. I need the entire document, which is larger than the window.

How do I observe this change?

like image 436
Steve Robbins Avatar asked Feb 14 '13 02:02

Steve Robbins


People also ask

How do you find the height of a document?

To get the height of a document, we can get the max of the scrollHeight , offsetHeight , or clientHeight properties. The document can be stored in the document. body or document. documentElement properties depending on the browser used.

What is $( document height ()?

$(document). height() returns an unit-less pixel value of the height of the document being rendered. However, if the actual document's body height is less than the viewport height then it will return the viewport height instead.


2 Answers

Update (Oct 2020):

resizeObserver is a wonderful API (support table)

// create an Observer instance const resizeObserver = new ResizeObserver(entries =>    console.log('Body height changed:', entries[0].target.clientHeight) )  // start observing a DOM node resizeObserver.observe(document.body)  // click anywhere to rnadomize height window.addEventListener('click', () =>   document.body.style.height = Math.floor((Math.random() * 5000) + 1) + 'px' )
click anywhere to change the height

Old answer:

Although a "hack", this simple function continuously "listens" (through setTimeout) to changes in an element's height and fire a callback when a change was detected.

It's important to take into account an element's height might change regardless of any action taken by a user (resize, click, etc.) and so, since it is impossible to know what can cause a height change, all that can be done to absolutely guarantee 100% detection is to place an interval height checker :

function onElementHeightChange(elm, callback) {   var lastHeight = elm.clientHeight, newHeight;    (function run() {     newHeight = elm.clientHeight;     if (lastHeight != newHeight)       callback(newHeight)     lastHeight = newHeight      if (elm.onElementHeightChangeTimer)       clearTimeout(elm.onElementHeightChangeTimer)      elm.onElementHeightChangeTimer = setTimeout(run, 200)   })() }  // to clear the timer use: // clearTimeout(document.body.onElementHeightChangeTimer);  // DEMO: document.write("click anywhere to change the height")  onElementHeightChange(document.body, function(h) {   console.log('Body height changed:', h) })  window.addEventListener('click', function() {   document.body.style.height = Math.floor((Math.random() * 5000) + 1) + 'px' })
LIVE DEMO
like image 164
vsync Avatar answered Sep 30 '22 14:09

vsync


You can use an absolute positioned iframe with zero width inside the element you want to monitor for height changes, and listen to resize events on its contentWindow. For example:

HTML

<body>   Your content...   <iframe class="height-change-listener" tabindex="-1"></iframe> </body> 

CSS

body {   position: relative; } .height-change-listener {   position: absolute;   top: 0;   bottom: 0;   left: 0;   height: 100%;   width: 0;   border: 0;   background-color: transparent; } 

JavaScript (using jQuery but could be adapted to pure JS)

$('.height-change-listener').each(function() {   $(this.contentWindow).resize(function() {     // Do something more useful     console.log('doc height is ' + $(document).height());   }); }); 

If for whatever reason you have height:100% set on body you'll need find (or add) another container element to implement this on. If you want to add the iframe dynamically you'll probably need to use the <iframe>.load event to attach the contentWindow.resize listener. If you want this to work in IE7 as well as browsers, you'll need to add the *zoom:1 hack to the container element and also listen to the 'proprietary' resize event on the <iframe> element itself (which will duplicate contentWindow.resize in IE8-10).

Here's a fiddle...

like image 20
Jake Avatar answered Sep 30 '22 15:09

Jake