杂记从iframe自适应高度实现及引出的几个ie问题的特殊处理

阅读更多

因为这是项目之后写的博客,因此这里只描述性的点出问题及解决的办法。

1、为了实现iframe动态加载页面并自适应高度,且兼容ie、FF、Chrome浏览器。以下为代码片段(引入Jquery):

 

 

 

$jq("#frametd").html('');
	$jq("#MainContent"+i).attr("src",uri);
	var iframe = $jq("#MainContent"+i)[0];
	if (iframe.attachEvent){ // 解决ie不认iframe onload问题
	     iframe.attachEvent("onload", function(){
	    	 iframe.height=iframe.contentWindow.document.body.scrollHeight;
		     });  
	 } else {  
	     iframe.onload = function(){ 
    		 iframe.height=iframe.contentWindow.document.documentElement.scrollHeight;
	     };  
	 }

/** 如果页面上还有ajax动态加载的component,ie还是不能拿到正确的height,只能在resize之后,再次去获取高度,此时拿到的height才是正确的 **/
function resize(i){
	 setTimeout("fixactualheight("+i+")",1);
}

function fixactualheight(i){
	try{
	var actualheight = $jq("#MainContent"+i).contents().find("body").height()+40;
	
	$jq("#MainContent"+i)[0].height=actualheight;
	}catch(e){
		setTimeout("fixactualheight("+i+")",10);
	}
}
 

 

 

以上代码,基本上都是为兼容ie浏览器编写的,因为其他浏览器实际上只需要一句代码onload时 iframe.height=iframe.contentWindow.document.documentElement.scrollHeight;就能实现高度自适应。
为什么ie里的实现会变的这么复杂呢?这跟动态加载的uri页面复杂度有关,如果iframe src加载的页面内容简单,页面本身没有动态异步加载,那就简单了,只要这句代码iframe.height=iframe.contentWindow.document.body.scrollHeight;就能实现高度自适应。但如果加载的页面本身又是通过比较复杂的js输出页面内容,这时候用以上这句代码获取的高度就会不正确。必须等到加载对像页面全部加载完毕后,才能获取到正确的高度。那如何捕获这个事件呢,直接用onresize还是不行,必须等到resize事件之后才能捕获,因此我这里的实现是在onresize事件里,再加上setTimeout(function(){},1)来捕获。

2、iframe的scrolling,在ie里能初始化,再次修改属性不起作用

一般情况下,如果iframe插入的页面很简单,没有弹出层,那自适应高度时,把scrolling初始化成no就行。但是如果iframe插入的页面又有弹出层,而且这个弹出层的高度可能超出页面自身高度,这时候如果不出现滚动条就不合理了。

这时就要把scrolling初始化成yes。但把scrolling置成yes后,在ie下某些iframe加载的页面,会出现一条disable后的滚动条,找不到原因,因为某些页面又没有,似乎跟插入的页面也有关系,我把获取到的高度iframe.contentWindow.document.body.scrollHeight再加上一定的高度,比如再加上500,这个disable后的滚动条就会消失,可能ie对是否出现滚条的内部判断机制有点问题。暂时无解,只能容忍让其出现这个假的滚动条。本人在实现的过程中,试图动态的修改scrolling属性,发现iframe的scrolling属性在ie下不能被动态设置,脚本不报错,但不起作用。

 

3、在实现过程中,间接引出ie的问题1,某些ie版本会自动给你的元素加style属性

$jq(obj).removeClass().addClass("newclass");

这是一个很简单的,为某个元素切换样式的代码,但在ie下发现怎么也不起作用,debug时才发现神奇的ie自行给当前元素加上了一段style。那就毫不客气的把style也一并删除,

$jq(obj).removeAttr("style").removeClass().addClass("newclass");

 

4、在实现过程中,间接引出ie(仅限ie6)的问题2,给select的option元素置selected属性不起作用。

看起来跟第2点有点相似的原因,解决的办法也是setTimeout,代码如下

 

 

 

if($jq.browser.msie && $jq.browser.version == "6.0"){
				/** ie6的一个bug,不能直接置selected值 **/
				setTimeout(function() { 
					$jq(youroption).attr("selected",true);
				}, 1);
                                setTimeout(function(){//你的后续业务},1);//这里一定要置1或比1大,不然获取的select值不对,因为前一步设置动作还没完成。
		}else{
 
			$jq(youroption).attr("selected",true);
                        //你的后续业务
		}

 

另外,如果iframe加载时存在跨域相关问题,参考之前的博文

 

 

你可能感兴趣的:(iframe高度自适应,iframe,高度自适应,scrolling,ie,bug)