考完试就来实习的公司实习了,大概最近有两周时间就一直在做公司给新人布置的大作业。虽然只是很简单的一个小的项目,但却从其中总结到了不少有用的东西。计划将其发出来一系列文章,算是对这两周时间的总结。也算是在这里留下记录,防止以后坑在同一个地方,接下来几周没事持续填坑吧。
在没来公司之前,我做过的项目也好,学习的新技术也好。从来都没有去想过去兼容IE6及以下版本的浏览器的,之前一段时间淘宝刚宣布不再继续支持IE6,刚好我做大作业的时候,百度也宣布不再继续支持IE6。但是来了公司之后接到的新人大作业之后,js与css布局都有一个共同的要求,兼容IE6,7浏览器。虽然很无奈,也知道IE6下坑很多,但毕竟也算是个尝试。所以就硬着头皮去做了。
做的一个小小的项目,总结出来的IE6浏览器与现代浏览器所不同的表现就有十几条。真是really心疼几年前的前端er,兼容IE6真的会让人抓狂。然后碰到的有IE6下被人熟知的BUG,也有自己碰到比较不常见的BUG,总结了几条,下面就慢慢道来吧。
一:IE6下浮动元素双倍margin。
具体表现就是当给一个父元素的第一个子元素向左、右浮动时,倘若在这个浮动方向上添加了margin值,在IE6下这个margin值会加倍。下面来看例子。
<div id="parent"> <p>IE6下浮动方向上的margin值将会变为设置值的两倍</p> </div>
#parent p{ float:left; margin-left:20px; }
可以自己试一下,在IE6下明显能看出比其他浏览器margin要大一点。
解决方案:1.利用css hack,给该元素添加_margin: 10px;也就是利用只有IE6能识别的hack,将其margin值设为本来要设置margin值的一半,这样IE6加倍之后,就和正常浏览器表现一致了。
2.将浮动元素设置为行内元素。display:inline;
二::IE6下html文件里的注释会影响布局/出现了文本的重复。
BUG原因:当满足如下公式,溢出文字的个数=注释的条数*2-1。注释就会造成元素高度变化/出现重复文本。
解决方案:1.不要写注释。。 2.利用<!—[IF !IE]>标签包围注释。
三:IE6下:hover只对a标签起作用。
BUG原因:css1不支持对除a标签之外的标签添加hover效果。
解决方案:这个算是比较经典的IE6的BUG了,解决的方案有很多种,我使用的是引入一个htc文件。htc文件就是专门用来解决IE下BUG的文件。这个原理是使用js来给元素定义onmouseover和onmouseout事件,使得所有标签在IE6下都可以支持hover事件。具体的使用方法如下,先定义一个csshover.htc文件,将如下代码复制进去。
<public:attach event="ondocumentready" onevent="CSSHover()" /><script> window.CSSHover=(function(){var m=/(^|\s)((([^a]([^ ]+)?)|(a([^#.][^ ]+)+)):(hover|active|focus))/i;var n=/(.*?)\:(hover|active|focus)/i;var o=/[^:]+:([a-z\-]+).*/i;var p=/(\.([a-z0-9_\-]+):[a-z]+)|(:[a-z]+)/gi;var q=/\.([a-z0-9_\-]*on(hover|active|focus))/i;var s=/msie (5|6|7)/i;var t=/backcompat/i;var u={index:0,list:[‘text-kashida‘,‘text-kashida-space‘,‘text-justify‘],get:function(){return this.list[(this.index++)%this.list.length]}};var v=function(c){return c.replace(/-(.)/mg,function(a,b){return b.toUpperCase()})};var w={elements:[],callbacks:{},init:function(){if(!s.test(navigator.userAgent)&&!t.test(window.document.compatMode)){return}var a=window.document.styleSheets,l=a.length;for(var i=0;i<l;i++){this.parseStylesheet(a[i])}},parseStylesheet:function(a){if(a.imports){try{var b=a.imports;var l=b.length;for(var i=0;i<l;i++){this.parseStylesheet(a.imports[i])}}catch(securityException){}}try{var c=a.rules;var r=c.length;for(var j=0;j<r;j++){this.parseCSSRule(c[j],a)}}catch(someException){}},parseCSSRule:function(a,b){var c=a.selectorText;if(m.test(c)){var d=a.style.cssText;var e=n.exec(c)[1];var f=c.replace(o,‘on$1‘);var g=c.replace(p,‘.$2‘+f);var h=q.exec(g)[1];var i=e+h;if(!this.callbacks[i]){var j=u.get();var k=v(j);b.addRule(e,j+‘:expression(CSSHover(this, "‘+f+‘", "‘+h+‘", "‘+k+‘"))‘);this.callbacks[i]=true}b.addRule(g,d)}},patch:function(a,b,c,d){try{var f=a.parentNode.currentStyle[d];a.style[d]=f}catch(e){a.runtimeStyle[d]=‘‘}if(!a.csshover){a.csshover=[]}if(!a.csshover[c]){a.csshover[c]=true;var g=new CSSHoverElement(a,b,c);this.elements.push(g)}return b},unload:function(){try{var l=this.elements.length;for(var i=0;i<l;i++){this.elements[i].unload()}this.elements=[];this.callbacks={}}catch(e){}}};var x={onhover:{activator:‘onmouseenter‘,deactivator:‘onmouseleave‘},onactive:{activator:‘onmousedown‘,deactivator:‘onmouseup‘},onfocus:{activator:‘onfocus‘,deactivator:‘onblur‘}};function CSSHoverElement(a,b,c){this.node=a;this.type=b;var d=new RegExp(‘(^|\\s)‘+c+‘(\\s|$)‘,‘g‘);this.activator=function(){a.className+=‘ ‘+c};this.deactivator=function(){a.className=a.className.replace(d,‘ ‘)};a.attachEvent(x[b].activator,this.activator);a.attachEvent(x[b].deactivator,this.deactivator)}CSSHoverElement.prototype={unload:function(){this.node.detachEvent(x[this.type].activator,this.activator);this.node.detachEvent(x[this.type].deactivator,this.deactivator);this.activator=null;this.deactivator=null;this.node=null;this.type=null}};window.attachEvent(‘onbeforeunload‘,function(){w.unload()});return function(a,b,c,d){if(a){return w.patch(a,b,c,d)}else{w.init()}}})(); </script>
接下来就是在你html文件的head头里按如下方式以正确的路径将其引进来,就可以完美解决IE6下hover只在a标签上有作用的BUG。
<!--[if lte IE 6]> <style type="text/css"> body { behavior:url("./css/csshover.htc"); } </style> <![endif]-->
四:IE6不支持子代选择器。
其实这个不算是IE6的BUG,而是IE8以下的浏览器都不支持子代选择器。
可以看下w3c的文档。https:www.w3.org/TR/css21/selector.html
解决方案:可以综合使用js获取子节点和给相应节点设置ID或者CLASS来解决。
五:IE6不支持getELementsByClassName。
这个是IE8以下都不支持的。
解决方案:利用浏览器能力检测,自己模拟一个getELementsByClassName方法。代码如下。
if(!document.getElementsByClassName){ document.getElementsByClassName = function(className, element){ var children = (element || document).getElementsByTagName(‘*‘); var elements = new Array(); for (var i=0; i<children.length; i++){ var child = children[i]; var classNames = child.className.split(‘ ‘); for (var j=0; j<classNames.length; j++){ if (classNames[j] == className){ elements.push(child); break; } } } return elements; }; }
六:IE6不支持边框透明。
这条呢,看上去貌似没什么,不支持边框透明,本来边框也不怎么设置透明这个值啊。那你就忽略了一种情况,要是用css画三角形来模拟下拉标识符时,就必须用到边框透明。
普通浏览器下这样设置
border-width: 4px 4px 0; border-color: #a4a4a4 transparent transparent;
IE6不支持边框透明,因此可以这样设置边框来模拟效果。设置要显示一边的三角其边框值为:border-style:solid,其他三边边框为border-style:dashed。这样便可以利用虚线样式的border形成空白。代码如下。
_border-width: 4px 4px 0; _border-color:#a4a4a4 white white white; _border-style:solid dashed dashed dashed;
七:IE6文本框不支持placeholder属性
解决方法:利用浏览器能力检测,为低版本浏览器添加value值来代替placeholder。
八:IE6不支持min/max-width/height属性
解决方法:添加如下所示代码
_width:expression(this.width>300?"300px":ture); max-width:300px;
但css表达式应该尽量避免使用。最好是给IE6添加_height/_width。
九:IE6下3px的像素偏差
当浮动元素与非浮动元素相邻,即使你没在俩元素之间设置边距,依然看上去会出现一条缝隙。
BUG原因:非浮动元素的layout未触发。
解决方案:1.将非浮动元素也设置为浮动。2.浮动元素设置display:inline 和 -3px margin