IE6上遮盖select,并解决页面滚动时,select闪烁有关问题

IE6下遮盖select,并解决页面滚动时,select闪烁问题
最近项目采用了jquery作为js库,easyui作为前提ui,但是它的的弹出宽遮罩没有解决IE6下select的穿透div层的问题,

进过讨论,决定采用iframe来覆盖select的方式解决。


用了iframe覆盖解决了传统问题,但是新的问题又出现了,如果页面有滚动条时,页面滚动的时候,被覆盖的select闪烁很厉害,页面停止了,闪烁也停止了,由于我们项目还采用了blockUI来自己弹出遮罩,发现blockUI也是采用iframe遮盖的方式:

// blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
	// layer1 is the iframe layer which is used to supress bleed through of underlying content
	// layer2 is the overlay layer which has opacity and a wait cursor (by default)
	// layer3 is the message content that is displayed while blocking

	var lyr1 = ($.browser.msie || opts.forceIframe) 
		? $('<iframe class="blockUI" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="'+opts.iframeSrc+'"></iframe>')
		: $('<div class="blockUI" style="display:none"></div>');
	var lyr2 = $('<div class="blockUI blockOverlay" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>');
	
	var lyr3, s;
	if (opts.theme && full) {
		s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+z+';display:none;position:fixed">' +
				'<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>' +
				'<div class="ui-widget-content ui-dialog-content"></div>' +
			'</div>';
	}
	else if (opts.theme) {
		s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+z+';display:none;position:absolute">' +
				'<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>' +
				'<div class="ui-widget-content ui-dialog-content"></div>' +
			'</div>';
	}
	else if (full) {
		s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:'+z+';display:none;position:fixed"></div>';
	}			
	else {
		s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement" style="z-index:'+z+';display:none;position:absolute"></div>';
	}
	lyr3 = $(s);


从以上代码可以看出它采用了3层来遮罩,
1,遮盖层(IE6及以下版本为iframe)
2,透明层
3,弹出遮罩时,信息显示层

IE6时,它又对这3层进行了fixed处理:
// simulate fixed position
		$.each([lyr1,lyr2,lyr3], function(i,o) {
			var s = o[0].style;
			s.position = 'absolute';
			if (i < 2) {
				full ? s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"')
					 : s.setExpression('height','this.parentNode.offsetHeight + "px"');
				full ? s.setExpression('width','jQuery.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"')
					 : s.setExpression('width','this.parentNode.offsetWidth + "px"');
				if (fixL) s.setExpression('left', fixL);
				if (fixT) s.setExpression('top', fixT);
			}
			else if (opts.centerY) {
				if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"');
				s.marginTop = 0;
			}
			else if (!opts.centerY && full) {
				var top = (opts.css && opts.css.top) ? parseInt(opts.css.top) : 0;
				var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"';
				s.setExpression('top',expression);
			}
		});

对第一,第二层宽,高定位;
对第三层top设定了一个表达式

对此,我也依样画葫芦的把它的代码搬到easyui中的window组件的遮罩中,最后发现我无论怎么设置,select还是会闪烁;
后来细细看了下代码,把他的不相关代码都注释掉,最后发现问题的关键是对第三层设定的top上,为了验证,我把blockUI的第三层div注释掉,果然select也闪烁;原来它的目的是当页面滚动时,自动调整第三层的top,使第三层固定保存在页面可视范围的顶部;

对此,我比对easyui中加入window组件中的代码,基本保存了blockUI的原理,可是select就是会闪烁,最后发现问题:
state.mask.css({
					zIndex: $.fn.window.defaults.zIndex++,
					width: getPageArea().width,
					height: getPageArea().height,
					display: 'none'
				});

原来这个遮罩height设定的问题,把height该成100%,问题解决。

为此,特别写了一个简单的html页面
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>ieselect.html</title>

  </head>
  
  <body>
  	<br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <select id="sel1"></select>
    <br>
    <select id="sel2"></select>
    <iframe id="iframe" style="z-index:9000;display:none;border:0;width:100%;height:100%;position:absolute;"></iframe>
    <div id="div" style="z-index:9001;display:none;width:100%;height:100%;position:absolute;"></div>
    <button onclick="display();">display</button>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
  </body>
  <script type="text/javascript">
  	
  	function $(id){
  		return document.getElementById(id);
  	}
  	
  	function display(){
  		$('iframe').style.left = 0;
  		$('iframe').style.top = 0;
  		$('iframe').style.height = Math.max(document.body.scrollHeight, document.body.offsetHeight);
  		$('iframe').style.display = 'block';
  		$('div').style.left = 0;
  		$('div').style.top = 0;
  		$('div').style.display = 'block';
  		$('div').style.setExpression('top', '(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"');
  	}
  	
  </script>
</html>