Document Height Change Event

Using an `absolute` positioned `iframe` to trigger an event listener when the document height changes for whatever reason

by davehol

HTML

<body>
  <!-- iframe for detecting height changes -->
  <iframe class="height-change-listener" tabindex="-1"></iframe>

  <!-- Demo -->
  <div id="console"></div>
  <label for="toggle-big">
    <input id="toggle-big" type='checkbox'/>
    Big
  </label>
  <label for="toggle-bigger">
    <input id="toggle-bigger" type='checkbox'/>
    Bigger
  </label>
  <div id="changeable"></div>
</body>

CSS

/* Element for which to detect height changes */
body {
  position: relative;
  *zoom: 1; /* otherwise IE7 does not update layout */
}
/* iframe within it for detecting height changes */
.height-change-listener {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  height: 100%;
  width: 0;
  border: 0;
  background-color: transparent;
}

/* Demo */
#changeable {
  border: 1px solid black;
  height: 200px;
  transition: height ease 0.5s
}
#changeable.bigger {
  height: 600px;
}
#changeable.big {
  height: 400px;
}
#changeable.big.bigger {
  height: 900px;
}
#console {
  float: right;
  height: 10em;
  width: 50%;
  overflow: auto;
  background-color: white;
  border: 1px solid grey;
  font-family: monospace;
}
#console p {
  margin: 0;
}

JavaScript

// Event handler for height changes
var onDocHeightChange = function() {
	// Demo
	var $console = $('#console');
	$console.append($('<p/>').text(
    'doc height is ' + $(document).height()
  )).scrollTop($console[0].scrollHeight);
}

// Set up height change event handler
// The contentWindow.resize event is for browsers;
// The <iframe>.resize event is for IE7 though will also fire on IE8-10
$('.height-change-listener').resize(onDocHeightChange).each(function() {
  $(this.contentWindow).resize(onDocHeightChange);
});

// Demo
$('#toggle-big').change(function() {
  $('#changeable').toggleClass('big', this.checked);
});
$('#toggle-bigger').change(function() {
  $('#changeable').toggleClass('bigger', this.checked);
});