最近需要做一个iframe调用其他页面内容,这个iframe地址是可变化的,但是里面的内容高度不确定且里面内容高度可调整,所以需要通过监听iframe里面body的高度变化来调整iframe的高度。
后面发现了一个好用的插件detect-element-resize.js,首先看一下这个插件的介绍:
插件简介
跨浏览器,基于事件,元素调整大小检测。
简而言之,此实现不使用内部计时器来检测大小更改(就像我发现的大多数实现一样)。它使用scroll大多数浏览器上的onresize事件,以及IE10及以下的事件。
使用的方法不仅检测javascript生成的调整大小更改,还检测CSS伪类的更改,例如:hover,CSS动画等。
插件兼容性
Chrome
Firefox
IE 11 及以下 (在11,10,9,8和7上测试)
已知问题
在IE 10及更低版本上:如果分离元素并重新附加它,则需要再次添加调整大小侦听器。
源代码
(function () {var attachEvent = document.attachEvent,stylesCreated = false;if (!attachEvent) {var requestFrame = (function(){var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||function(fn){ return window.setTimeout(fn, 20); };return function(fn){ return raf(fn); };})();var cancelFrame = (function(){var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || ??window.clearTimeout; ?return function(id){ return cancel(id); };})();function resetTriggers(element){var triggers = element.__resizeTriggers__,expand = triggers.firstElementChild,contract = triggers.lastElementChild,expandChild = expand.firstElementChild;contract.scrollLeft = contract.scrollWidth;contract.scrollTop = contract.scrollHeight;expandChild.style.width = expand.offsetWidth + 1 + ‘px‘;expandChild.style.height = expand.offsetHeight + 1 + ‘px‘;expand.scrollLeft = expand.scrollWidth;expand.scrollTop = expand.scrollHeight;};function checkTriggers(element){return element.offsetWidth != element.__resizeLast__.width || element.offsetHeight != element.__resizeLast__.height;}function scrollListener(e){var element = this;resetTriggers(this);if (this.__resizeRAF__) cancelFrame(this.__resizeRAF__);this.__resizeRAF__ = requestFrame(function(){if (checkTriggers(element)) {element.__resizeLast__.width = element.offsetWidth;element.__resizeLast__.height = element.offsetHeight;element.__resizeListeners__.forEach(function(fn){fn.call(element, e);});}});};/* Detect CSS Animations support to detect element display/re-attach */var animation = false,animationstring = ‘animation‘,keyframeprefix = ‘‘,animationstartevent = ‘animationstart‘,domPrefixes = ‘Webkit Moz O ms‘.split(‘ ‘),startEvents = ‘webkitAnimationStart animationstart oAnimationStart MSAnimationStart‘.split(‘ ‘),pfx ?= ‘‘;{var elm = document.createElement(‘fakeelement‘);if( elm.style.animationName !== undefined ) { animation = true; } ???if( animation === false ) {for( var i = 0; i < domPrefixes.length; i++ ) {if( elm.style[ domPrefixes[i] + ‘AnimationName‘ ] !== undefined ) {pfx = domPrefixes[ i ];animationstring = pfx + ‘Animation‘;keyframeprefix = ‘-‘ + pfx.toLowerCase() + ‘-‘;animationstartevent = startEvents[ i ];animation = true;break;}}}}var animationName = ‘resizeanim‘;var animationKeyframes = ‘@‘ + keyframeprefix + ‘keyframes ‘ + animationName + ‘ { from { opacity: 0; } to { opacity: 0; } } ‘;var animationStyle = keyframeprefix + ‘animation: 1ms ‘ + animationName + ‘; ‘;}function createStyles() {if (!stylesCreated) {//opacity:0 works around a chrome bug https://code.google.com/p/chromium/issues/detail?id=286360var css = (animationKeyframes ? animationKeyframes : ‘‘) +‘.resize-triggers { ‘ + (animationStyle ? animationStyle : ‘‘) + ‘visibility: hidden; opacity: 0; } ‘ +‘.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: \" \"; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }‘,head = document.head || document.getElementsByTagName(‘head‘)[0],style = document.createElement(‘style‘);style.type = ‘text/css‘;if (style.styleSheet) {style.styleSheet.cssText = css;} else {style.appendChild(document.createTextNode(css));}head.appendChild(style);stylesCreated = true;}}window.addResizeListener = function(element, fn){if (attachEvent) element.attachEvent(‘onresize‘, fn);else {if (!element.__resizeTriggers__) {if (getComputedStyle(element).position == ‘static‘) element.style.position = ‘relative‘;createStyles();element.__resizeLast__ = {};element.__resizeListeners__ = [];(element.__resizeTriggers__ = document.createElement(‘div‘)).className = ‘resize-triggers‘;element.__resizeTriggers__.innerHTML = ‘<div class="expand-trigger"><div></div></div>‘ +‘<div class="contract-trigger"></div>‘;element.appendChild(element.__resizeTriggers__);resetTriggers(element);element.addEventListener(‘scroll‘, scrollListener, true);/* Listen for a css animation to detect element display/re-attach */animationstartevent && element.__resizeTriggers__.addEventListener(animationstartevent, function(e) {if(e.animationName == animationName)resetTriggers(element);});}element.__resizeListeners__.push(fn);}};window.removeResizeListener = function(element, fn){if (attachEvent) element.detachEvent(‘onresize‘, fn);else {element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);if (!element.__resizeListeners__.length) {element.removeEventListener(‘scroll‘, scrollListener);element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__);}}}})();
调用方法
addResizeListener(element,fun) ???//element为监听的元素,fun为当有变化时触发的方法//例如监听body的高度变化:addResizeListener(document.getElementsByTagName("body")[0],detectCallback);var detectCallback = function() { ?????console.log(‘页面body高度发生了变化‘)};
实例:
监听iframe页面变化时iframe的高度等于iframe里面页面body的高度
<iframe src="url" frameborder="0" id="container"></iframe>//iframe 页面代码window.onload=function(){ ???setParentIframeHeight(‘container‘); ???addResizeListener(document.getElementsByTagName("body")[0], detectCallback);}var detectCallback = function() { ?setParentIframeHeight(‘container‘);};function setParentIframeHeight(id){ ???var parentIframe = parent.document.getElementById(id); ???parentIframe.height = document.body.scrollHeight;}
detect-element-resize.js插件地址:https://github.com/sdecima/javascript-detect-element-resize
js监听某个元素高度变化来改变父级iframe的高度
原文地址:https://www.cnblogs.com/gxsyj/p/9860807.html