onElementResize 0.3

by moob

HTML

<div id="testdiv" class="testItem">This div grows on hover.</div>
    <div id="testdiv2" class="testItem resizable">This div is resizable (if supported by your browser).</div>
    <div id="testdiv3" class="testItem" contenteditable="true">This div is content-editable (if supported by your browser).</div>
    <p>This iFrame should automatically resize to fit its contents.</p>
<iframe id="testiframe" name="ifr" src="wont work here due to CORS" />

CSS

html, body {margin:0;}
    body {padding: 20px; font-family: sans-serif; }
    iframe {width:100%;}
    #testdiv, .testItem {padding:20px; margin:20px; background-color: #dddddd;}
    #testdiv {transition: all 0.5s ease;}
    #testdiv:hover {padding:50px 20px;}
    .resizable {width:200px; resize:both; overflow:auto;}

JavaScript

/* onElementResize.0.3.js */
//use requestAnimationFrame for smoothness (shimmed with setTimeout fallback)
window.rAF = window.rAF || (function(){
  return  window.requestAnimationFrame       ||
		  window.webkitRequestAnimationFrame ||
		  window.mozRequestAnimationFrame    ||
		  function( callback ){
		  		window.oldschool = true;
				window.setTimeout(callback, 1000 / 30);
		  };
})();

(function ($) {

	$.fn.onElementResize = function (callback) {
				
		return this.each(function () {
			var el = this,
				$el = $(el);
			/* if el is an iframe we need to target the body or html rather than the element itself 
			Apparently IE has issues (unsurprisingly) so we may have to use an inline onload event for the iframe
			http://stackoverflow.com/questions/4955076/jquery-iframe-body-selector */
			var iFrame = (el.tagName.toLowerCase()=="iframe");
			if(iFrame){
				//IFRAME might not be loaded!
				if (!$el.contents().find('body').children().length > 0) {
					//console.warn("iframe not ready");
					//(possibly this would never be ready so abort after x seconds)
					var now = new Date().getTime();
					var diff = now - ($el.data("timer") || now);
					if(diff>=10000){//taking too long (allow 10 seconds)
						if(console && console.warn){console.warn("onElementResize iFrame taking too long to load!");}
						return false;
					}
					$el.data("timer",now);
					return $el.load(function(){$el.onElementResize(callback);});
				}
				//set el to be the iframe            
				el = $el.contents().find("html")[0];//might be dodgy for IE
				//console.log("EL",el);
			}
			//measure the inital size:
			var width = Math.max(el.offsetWidth, el.scrollWidth),
				height = Math.max(el.offsetHeight, el.scrollHeight);
			//trigger initial resize on load by trickery
			if(iFrame){
				width = width-1;
				height= height-1;
			}
			//set up a loop
			(function loop(){
				//IE8 jumps to top(ish) EVERY TIME the css.height set/removed because the iframe collapses thus changes the...