• js监听某个元素高度变化来改变父级iframe的高度


    最近需要做一个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=286360
    			var 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%;  100%; overflow: hidden; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before {  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

  • 相关阅读:
    Codeforces Round #239(Div. 2) 做后扯淡玩
    hdu 3507 Print Article
    prufer序列
    POJ 2778 DNA Sequence
    Codeforces Round #237 (Div. 2)
    poj3352
    图论知识
    POJ 2186
    Codeforces Round #236 (Div. 2)
    POJ 2823 Sliding Window
  • 原文地址:https://www.cnblogs.com/gxsyj/p/9860807.html
Copyright © 2020-2023  润新知