当前位置: 秋叶网络博客 前端编程 ◊ 从谷歌浏览器到IE11到IE6兼容的漫漫长途

从谷歌浏览器到IE11到IE6兼容的漫漫长途

作者:秋了秋 发表时间:2015年08月06日

前言:泱泱大国,居然被一个IE浏览器牵扯得颠沛流离,IE到底有多大的普及力量,就好比中国的迷信思想,像鬼魂一样挥之不去。纵使像chromium这样高级的浏览器问世以及目前的新技术css3和html5的出现使得页面展示得更加活色活香。然而懂得品味的人并不多,用着ie的钉子户还占着巨大的市场。除了ie之外还有众多的浏览器,她们各自对网页的识别标准都不一样,非常杂乱,这给前端工程师无疑是个非常大的打击,可以说没有一个前端工程师不恨ie的,恨得咬牙切齿。然而有时考虑到广大的终端用户的浏览体验以及客户的需求,不得不做兼容性调试,特别是大型站点,ie兼容显得更不可少。以前一直认为百度的网站丑啦吧唧的,不知道百度的前端工程师是干嘛的,有些网站其实我们只看到了表面,却不知道内部的技术层次,就拿百度来说,它不但兼容ie,而且还兼容ie6,更不可思议的是还兼容ie5,虽然有报错,但兼容率比较高,虽然它的前端没用到什么高级技术,然而有些高级技术也可以做到在ie上展示的,这就是本文要讲的:从chromium到IE11到IE6兼容的漫漫长途。

1.让ie浏览器兼容html5语义

用html5标签网页写网页已经越来越成为趋势了,html5被炒得沸沸扬扬,很多客户都愿意花巨资用html5做网页,然而他们并不知道html5其实就是在html4的基础上多了几个标签少了几个标签而已。html5真正的技术含量在于js的操作而非html。单纯的用html5写网页的话只需要把一些特定的div标签换成<article>、<header>、<nav>、<section>、<aside>、<footer>....即可,当然还需要把网页头部的

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

换成

<!DOCTYPE html>

但是当网页实现了html4变成html5之后,ie浏览器就不认识网页了,特别是以上所列的这些标签,造成在ie上浏览布局错乱,解决办法还是有的,只需要在网页头部中加入:

<!--[if lt IE 11]>
<script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<![endif]-->

原理就是用js向网页中插入这些标签,为防止地址失效,贴出代码,html5shiv.min.js里面的代码为:

展开/收缩
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.2",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b)}(this,document);

2.让ie浏览器兼容响应式网页,所谓响应式网页就是css中用到了css3,ie浏览器一样识别不了,造成在ie浏览器下响应式无效。 要实现网页的响应式能在手机端呈现出来,必须在网页头部加上:

<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1">

不加的话,显示的效果还是以pc端方式来展现网页,所以这个必须加,非ie下也要加。要让其在ie下也能展现还要在网页头部加上以下代码: <!--[if lt IE 11]> <script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script> <![endif]--> respond.min.js文件的代码为:

展开/收缩
!function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='&shy;<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b<s.length;b++){var c=s[b],e=c.href,f=c.media,g=c.rel&&"stylesheet"===c.rel.toLowerCase();e&&g&&!o[e]&&(c.styleSheet&&c.styleSheet.rawCssText?(v(c.styleSheet.rawCssText,e,f),o[e]=!0):(!/^([a-zA-Z:]*\/\/)/.test(e)&&!r||e.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&("//"===e.substring(0,2)&&(e=a.location.protocol+e),d.push({href:e,media:f})))}w()};x(),c.update=x,c.getEmValue=t,a.addEventListener?a.addEventListener("resize",b,!1):a.attachEvent&&a.attachEvent("onresize",b)}}(this);

为了防止疏漏,再加上一段终极代码:

<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

这段代码的意思是如果访问者的电脑安装有ie的其它版本浏览器或谷歌内核浏览器,就让当前网页以最高级别的可用模式显示内容来渲染。这个是相当给力的,因为有很多ie钉子户装了其它浏览器的,只是默认浏览器没修改过来,每次打开网页依然用ie低版本浏览器,这句代码就好像专为这些人准备的。


做完以上工作,ie兼容的工作已经是做了一半了,至少在ie浏览器下网页不会出现很大的布局错乱问题,但是小bug还是层出不穷的,这就源于一些不可改观的因素极其一些css和js不规范和不严谨的写法造成的。我们所能做的就是写规范写严谨,以下分享我在最近项目中亲身遇到的一些问题的解决办法:

1.js除错提示,在ie下难免会有js兼容问题,总是会弹出一些报错窗口,我的人会有疑问,我用ie没有什么弹出窗口,后面我会提供标准的不同版本低级ie浏览器供大家测试。要禁止这些弹窗,只需在网页head里面&网页所有js前面添加以下扼杀代码:

<script>function killErr(){return true;}window.onerror=killErr;</script>

相当于浏览器在窗口弹出前自动帮你把弹出窗口选择“确定”。 2.ie6下.png图片不透明的解决方案。

ie6下图片如果含有透明成分将会把透明成分变成白色,关于这个问题很多人都说用js来处理,但我试了下没有一个理想的效果,反而出现各种bug,其实问题本身并不在代码身上,而是图片上,图片采用了png24格式造成的。只要把图片用ps另存为web所用格式中的png8格式就可以完美兼容ie6,虽然像素png8比png24低了点,但无伤大雅,一般是看不出来的。

3.字体的兼容:在普通浏览器下,我们用css单独定义某个元素块的字体通常用好几种字体并排,如font-family:"宋体","微软雅黑","Arial, Lucida Grande, Tahoma";目的就是告诉浏览器,默认用宋体,如果用户设备没有宋体就用微软雅黑,依次读过去。但在ie浏览器下看到的字体往往跟谷歌等的浏览器大相径庭,是因为ie引用了这其中的另外一种字体。因为它的读取顺序是从后面开始,解决办法就是把你想要的字体再复制到后面font-family:"宋体","微软雅黑","Arial, Lucida Grande, Tahoma","宋体";

关于火狐浏览器对字体的兼容,火狐就更加奇葩,它是即使用户安装有该字体,它也是不显示的,它就喜欢自作主张的用它的微软雅黑字体,解决办法除了浏览器上的设置以外,就是用它能识别的字体,比如说“宋体”,至于它还能识别其它什么字体,笔者没时间去一一测试,问问火狐开发人员吧~

4.修改css属性不生效的解决办法,这种情况一般是我们对span和a标签加样式常遇到的问题,因为span和a标签不是块级元素,,你要让css对其有效果,必须加上display:block;虽然默认的样式就是这个,但是还是要加上使其变为块级元素,至于哪些是块级元素哪些不是,这里不做探讨,只要记住遇到修改css不起作用的情况除了缓存外,就是要给它加一个display:block;了,往往能是你如愿。

5.div自适应高度问题:理论上一个如果不设置div的高度的话,它默认高度是自适应的,即随着div里面的内容所占高度而变化,但是有时候我们经常遇到有内容父级div高度为0,造成下一级的div的margin-top异常现象以及自身背景颜色不显示的情况,这是因为该div里面的所有元素都是浮动属性,解决办法就是在div里面添加一个空的div,让它清除浮动属性。如:

<div class="fuji">
<div style="float:left"></div>
<span style="float:right"></span>
<div style="clear:both"></div>
</div>

div的clear属性

clear:both是清除浮动的属性,别小看这个东西,很有用处,往往能在你遇到莫名其妙的情况下把你救起,很多异常情况都是源于浮动问题,比如说div莫名其妙包含上一级的div,只需要将该div设置clear:both

6.使input的光标居中:input输入框的css属性尽量不要用padding,包括所有的html容器也是一个道理,不要用padding来充当高度来使用,否则的高度会随里面的内容而改变,包括字体类型,字体大小,而这些往往在不同浏览器又有所不一样,特别是input输入框,上下padding一定要设为0,然后用height来设定高度,在把line-height值设成跟高度一样,这样光标以及文字就会上下居中。

7.布局错乱的一大杀手position:fixed;ie低版本浏览器是不认识这个东西的,所以本身是position:fixed;元素块将会以relative方式插在网页中,把其它内容撑开,导致布局错乱的现象。解决办法就是增加ie浏览器识别的另外一种属性_position:absolute,如下:

body {
_background-attachment:fixed;
}
#xxx { width:68px; height:100px; right:-5px; margin:0 auto; position:fixed; clear:both _position:absolute; _top:expression((offsetParent.scrollTop)+150);//距离顶部的高度 _left:expression(offsetParent.scrollLeft);//距离左边的高度 }

本文更新中......

推荐使用的浏览器:360安全浏览器或360极速浏览器或谷歌浏览器,另外秋叶网络博客现今的兼容程度(按照美观性和功能):360安全浏览器兼容率100%,360极速浏览器和谷歌浏览器兼容率98%,ie11兼容率95%,火狐浏览器兼容率90%,ie8兼容率88%,ie7浏览器兼容率88%,ie6浏览器兼容率87%,ie9兼容率70%,ie5浏览器兼容率10%。

说明:兼容率在ie下是不可能达到100%完美状态的,没有最好,只有更好,做兼容本来就是确保主要功能不受影响而已,别对自己在这方面有太苛刻的想法,以及别对前端人员在这方面有太高层次的要求,不要有把饼干变成石头的想法,否则终会失望告终。

作为一个前端人员我是这样想的:统一浏览器比统一祖国更重要。

标准ie5、6、7、8、9、11各版本浏览器兼容性测试软件下载[dd]http://pan.baidu.com/s/1dD8S6Bn[/dd]

0
除非注明,文章均由 秋叶网络博客 发布,欢迎转载。
转载请注明本文地址:http://www.mizuiren.com/372.html
目录: 前端编程 | 标签: 兼容ie6, 前端兼容 | 20662次阅读