浏览器与兼容性

216 阅读9分钟

一、兼容性产生原因:

因为不同浏览器使用内核及所支持的HTML等网页语言标准不同;以及用户客户端的环境不同(如分辨率不同)造成的显示效果不能达到理想效果。最常见的问题就是网页元素位置混乱,错位。兼容性产生原因主要是内核或内核的版本不一样;

二、浏览器对网页兼容支持的解析模式:

1、为什么会有那么多模式?

由于历史的原因,各个浏览器在对页面的渲染上存在差异,甚至同一浏览器在不同版本中,对页面的渲染也不同。在W3C标准出台以前,浏览器在对页面的渲染上没有统一规范,产生了差异(Quirks mode或者称为Compatibility Mode);由于W3C标准的推出,浏览器渲染页面有了统一的标准(CSScompat或称为Strict mode也有叫做Standars mode),这就是二者最简单的区别。

2、浏览器采用哪种模式进行解析呢?

火狐一直工作在标准模式下,但IE(6,7,8)标准模式与怪异模式差别很大, 主要体现在对盒子模型的解释上,

那么浏览器究竟该采用哪种模式渲染呢?这就 引出的DTD,既是网页的头部声明,浏览器会通过识别DTD而采用相对应的渲染模式:

\1. 浏览器要使老旧的网页正常工作,但这部分网页是没有doctype声明的,所以 浏览器对没有doctype声明的网页采用quirks mode解析。

\2. 对于拥有doctype声明的网页,什么浏览器采用何种模式解析,这里有一张详细列表可参考: hsivonen.iki.fi/doctype。 

\3. 对于拥有doctype声明的网页,这里有几条简单的规则可用于判断: 对于那些浏览器不能识别的doctype声明,浏览器采用strict mode解析。

\4. 在doctype声明中, 没有使用DTD声明或者使用HTML4以下(不包括HTML4)的DTD声明时,基本所有的浏览器都是使用quirks mode呈现,其他的则使用strict mode解析。

\5. 可以这么说,在 现有有doctype声明的网页,绝大多数是采用strict mode进行解析的。

\6. 在ie6中,如果在doctype声明前有一个xml声明(比如:),则采用quirks mode解析。这条规则在ie7中已经移除了。

3、如何设置为怪异模式(quirks mode)和标准模式(strict mode):

3.1、设置怪异模式:

方法一:在页面项部加

方法二:什么也不加。

3.2、设置为标准模式:

加入以下任意一种:HTML4提供了三种DOCTYPE可选择:

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd”>

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd”>

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Frameset//EN” “http://www.w3.org/TR/html4/frameset.dtd”>

XHTML1.0提供了三种DOCTYPE可选择:

(1)过渡型(Transitional )

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

(2)严格型(Strict )

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>

(3)框架型(Frameset )

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

备注:过渡型和严格型的区别:

Transitional DOCTYPEs只是为了实现从旧时代到新时代的过渡,而且Strict DOCTYPEs是默认的文档声明, 对构造HTML 4.01和XHTML 1.0都适用。

使用Transitional DOCTYPE一般是由于代码中含有过多陈旧的写法,并且一下子很难完全转换到Strict DOCTYPE来。但是Strict DOCTYPE才应该是你的目标。它鼓励甚至有时是强迫你把结构与表现区分开来,把表现层的代码都写在CSS里,将结构和表现分开,使得维护一个站点非常容易。

对于准备向Strict进发的人来说,两者的有些区别很可能会使开发者犯错误,接下来我将会谈到。

在Strict DOCTYPEs下不支持的标签

center font iframe srike u 在Strict DOCTYPEs下不支持的属性 align (表格相关的支持:col, colgroup, tbody, td, tfoot, th, thead, and tr) language background bgcolor border (table支持) height (img和object支持) hspace name (在HTML 4.01 Strict中支持,XHTML 1.0 Strict中的form和img不支持) noshade nowrap target text, link, vlink, 和alink vspace width (img, object, table, col, 和 colgroup都支持)

内容模型的区别

元素类型的内容模型描述了什么样的元素类型实例可以被包含。这一点上,两种文档声明的最大区别在于blockquote, body, 和form元素仅能够包含块级元素,如: 文本和图像不允许直接包含在body中,必须被p或者div等块级元素包含 input元素不能直接是form元素的下一层 blockquote元素内的文本,必须被p或者div等块级元素包含 将所有的表现都交给CSS,恪守Strict标准

在向Strict DOCTYPEs过渡的过程中,了解每个元素是做什么的比知道每个元素长啥样有效的多。

4、如何判定现在是标准模式还是怪异模式:

方法一:执行以下代码 

alert(window.top.document.compatMode) ;

//BackCompat 表示怪异模式

//CSS1Compat 表示标准模式

方法二:jquery为我们提供的方法,如下:

alert($.boxModel)

alert($.support.boxModel)

三、不同浏览器间的兼容问题及解决方法

1、 CSS resert: 抹去不同浏览器的默认属性,使得不同浏览器兼容性问题降到最低,最好可以根据项目情况设置css resert代码。

  • 缺点主要是:抹去浏览器默认属性、在浏览器调式工具有大量继承链

2、CSS hack

2.1 定义:CSS hack由于不同厂商的浏览器,比如Internet Explorer,Safari,火狐,Chrome等,或者是同一厂商的浏览器的不同版本,如IE6和IE7,对CSS的解析认识不完全一样,因此会导致生成的页面效果不一样,得不到我们所需要的页面效果。 这个时候我们就需要 针对不同的浏览器去写不同的CSS,让它能够同时兼容不同的浏览器,能在不同的浏览器中也能得到我们想要的页面效果,CSS hack书写顺序,一般是将适用范围广、被识别能力强的CSS定义在前面。

2.2 分类

CSS Hack大致有3种表现形式, CSS属性前缀法、选择器前缀法以及IE条件注释法(即HTML头部引用if IE)Hack,实际项目中CSS Hack大部分是针对IE浏览器不同版本之间的表现差异而引入的。

解决兼容性的办法:

一、样式初始化

由于各大浏览器会有自身的默认样式,并且不尽相同,所以为了尽可能的保证样式的统一性,前端在开发项目之前都会先进行样式格式化,最常见的分为以下几个方面。

1. pandding 值和 margin 值均设置为 0

将html、body、a、li、ol、input、textarea、select、button 等标签的 padding 值和 margin 值设置为 0。

2.html 标签

设置统一的字体,如果使用 rem 单位,则 html 需要设置合适的字号。

3.a 标签

设置统一的颜色,将 text-decoration 属性设置为 none。

4.ol 和 li 标签

list-style 统一设置为 none。

5.input、textarea、select、button 等标签初始化

border 设置为 none;

二、使用不同类型的浏览器内核前缀

1.Chrome(谷歌浏览器) 与 Safari(苹果浏览器) 内核:Webkit (中译无) 前缀:-webkit-

2.IE (IE浏览器) 内核:Trident (中译三叉戟) 前缀:-ms-

3.Firefox (火狐浏览器) 内核:Gecko(中译壁虎) 前缀:-moz-

4.Opera (欧朋浏览器) 内核:Presto(中译迅速) 前缀:-o-

-webkit-border-radius: 10px; /*谷歌浏览器*/
-ms-border-radius: 10px;     /*IE浏览器*/
-moz-border-radius: 10px;    /*火狐浏览器*/
-o-border-radius: 10px;      /*欧朋浏览器*/
border-radius: 10px; 

三、针对IE浏览器不同版本的解决方案(CSS hack

1.对于低版本的 IE 浏览器使用 CSS hack( 即给特点前缀)

注:以下符号是写在属性名前面。

兼容 IE6 的 hack 符号:- 或 _

兼容 IE6 、7 的 hack 符号:` ~ ! @ # $ % ^ & * ( ) + = [ ] | < > , . 任意一个符号

兼容 IE6、7、8 的 hack 符号:.

注:以下符号是写在属性值与分号直接,中间不留空格。

兼容 IE8 的 hack 符号:\0/

兼容 IE8、9、10 的 hack 符号:\0

兼容 IE6、7、8、9、10 的 hack 符号:\9

/*hack符号在前*/
_border-radius: 10px;   /*IE6*/
+border-radius: 10px;   /*IE6\7*/
.border-radius: 10px;   /*IE6\7\8*/
 
/*hack符号在后*/
border-radius: 10px\0/;   /*IE8*/
border-radius: 10px\0;   /*IE8\9\10*/
border-radius: 10px\9;   /*IE6\7\8\9\10*/

2.为不同的版本编写独立的样式,其他浏览器识别不到。

大于 IE9 的浏览器使用这个单独的 style9.css 样式

<!--[if gte IE 9]> 
 	<link rel="stylesheet" href="style9.css">
<![endif]-->

只有 IE6 浏览器使用的 style6.css 样式

<!--[if IE 6]>
   <link rel="stylesheet" href="style6.css">
<![endif]-->

四、其他特殊样式

1.cursor 属性的 hand 值和 pointer 值

问题:firefox 浏览器不支持 hand 值,但其他浏览器均支持 pointer 值。 解决: 统一使用 cursor 属性的 pointer 值。

2.水平居中

问题:IE8 及IE8 以下版本浏览器不可通过设置 margin:0 auto 实现水平居中。 解决: 可通过设置父级 text-align:center 实现。

3.属性值 "inherit"

问题:IE8 及IE8 以下版本浏览器不支持属性值 "inherit"。 解决:谨慎使用属性值 "inherit"。

五、JS兼容性

1.ES6语法

问题:IE11 不支持箭头函数、class 语法等(报 SCRIPT1002: 语法错误),不支持 Set 和 Map 数据结构(不报错)及 Promise 对象,支持 let 和 const,IE10 及以下不支持任何 ES6 语法。 解决:如果要兼容IE浏览器的项目请使用 ES5 语法或者使用 Babel 进行转换。

2.操作 tr 标签

问题:IE9 及 IE9 以下版本浏览器,不能操作 tr 标签的 innerHTML 属性。 解决:可以操作 td 标签的 innerHTML 属性。

3.Ajax

问题:IE9 及 IE9 以下版本浏览器无法使用 Ajax 获取接口数据。 解决:在使用 Ajax 请求之前设置 jQuery.support.cors=true。

4.event 对象的 srcElement 属性

问题:IE8 及 IE8 以下版本浏览器 event 对象只有 srcElement 属性,没有 target 属性。 解决:obj = event.target?event.target:event.srcElement。

5.DOM 事件绑定

问题:IE8 及 IE8 以下版本浏览器是用 attachEvent() 方法,而其他浏览器是 addEventListener() 方法。 解决:判断 IE 浏览器版本,如果是 IE8 及以下 事件绑定则使用 attachEvent() 方法,注意 attachEvent() 方法的用法,第一个参数为“onclick” 而不是“click”。并且没有第三个参数。