为什么会存在浏览器兼容问题?
首先要了解兼容,我们先得了解一下为什么会存在浏览器兼容问题。在各大浏览器厂商的发展过程中,它们对 web 的标准各有不同的实现,标准不同存在差异所以产生兼容性的问题。
浏览器内核
五大浏览器内核以及各内核代表作品:
- Trident: IE、Maxthon(遨游)、Theworld(世界之窗)
- Gecko: Mozilla Firefox
- Webkit: Safari、Chrome
- Presto: Opera
- Blink: 由 Google 和 Opera Softwase 开发的浏览器排版引擎
一些概念
-
CSS BUG
Css 样式在各浏览器中解析不一致的情况,或者说 Css 样式在浏览器中不能正确显示的问题称为 CSS Bug
-
CSS hack
CSS 中,hack 是指一种兼容 css 在不同浏览器中正确显示的技巧方法,因为他们都属于个人对 css 代码的非官方的修改,或非官方的补丁。有些人更喜欢使用 patch(补丁)来描述这种行为。
-
Filter
它是一种对特定的浏览器或浏览器组显示或隐藏规则或声明的方法。本质上讲,filter 是一种用来过滤不同浏览器的 hack 类型。
过滤器(filter)
ps:过滤器可能这个说法有点不太正确,也可以说是浏览器标识符!
-
_下划线过滤器
当一个属性前面增加一个下划线后,由于符合标准的浏览器不能识别带有下划线的属性而忽略了这个声明。但是 ie6 及更低版本浏览器会继续解析。
语法:选择器 {_属性:属性值;}
此方法是区分 ie6 浏览器和其他浏览器的方法 -
!important 关键字过滤器
它表示所附加的声明具有最高优先级的意思,被浏览器优先显示(ie6 不识别此写法)
语法:选择符{属性:属性值!important;} -
* 属性过滤器
当一个属性前面加了 * 后,该属性能被 ie7 及以下浏览器识别,其他浏览器忽略该属性的作用
语法:选择器{* 属性:属性值;} -
+ 属性过滤器
当一个属性前面加了 + 后,该属性能被 ie7 及以下浏览器识别,其他浏览器忽略该属性的作用
语法:选择器{+ 属性:属性值;} -
*+ 属性过滤器
当一个属性前面加了 *+ 后,该属性能被 ie7 浏览器识别,其他浏览器忽略该属性的作用
语法:选择器{*+ 属性:属性值;} -
9
ie 版本识别,其他浏览器不识别
语法:选择符{属性:属性值 \9;} -
0
ie8 及以上浏览器识别,其他浏览器不识别
语法:选择符{属性:属性值 0;} - -moz-
Firefox 浏览器识别,其他浏览器不识别
- -webkit-
webkit 内核浏览器识别,其他浏览器不识别
- -o-
Opera 浏览器识别,其他浏览器不识别
- -ms-
ie 浏览器识别,其他浏览器不识别
常见的浏览器兼容问题以及解决方法
1)、图片有边框 bug
描素: 当图片加在 ie 上会出现边框
hack: 给图片加 border:0;或者 border:0 none;
2)图片间隙
描素:div 中的图片间隙 bug
在 div 中插入图片时图片将 div 下方撑大大约三像素
hack1:将 </div> 与 <img> 写在一行上;
hack2:将 <img> 转换为块级元素,给 <img> 添加声明 display:block;
3)双倍浮向(双倍边距)(只有 ie6 出现)
描素: 当 ie6 及更低版本浏览器在解析浮动元素时会错误的把浮动边边距(margin)加倍显示。
hack:给浮动元素添加声明:display:inline;
4)默认高度(ie6 ie7)
描述:在 ie6 及以下版本中,部分块元素拥有默认高度(在 16px 左右)
hack1:给元素添加声明:font-size:0;
hack2: 给元素添加声明:overflow:hidden;
5)表单元素行高对齐不一致
描素:表单元素行高对齐方式不一致
hack:给表单元素添加声明:float:left;
6)按钮元素默认大小不一
描素:各浏览器中按钮大小不一致
hack1:统一大小 /(用 a 标记模拟)
hack2:input 外边套一个标签,在这个标签里写按钮的样式,把 input 的边框去掉
hack3: 如果这个按钮是一个图片,直接把图片作为按钮的背景图即可。
7)百分比 bug
描素:在 ie6 以及以下版本中解析百分比时会四舍五入方式计算从而导致 50% 加 50% 大于 100% 的情况。(也会受系统影响)
hack:给右边的浮动元素添加声明
8)li 列表的 bug
(1)当父元素 li 有 float:left;子元素 a 没设置浮动的情况下会出现垂直 bug;
hack:给父元素 li 和子元素 a 都设置浮动
(2)当 li 中的 a 转成 block;并且有 height 并有 float 的 li 没设置浮动会出现阶梯显示
hack:同时给 li 加 float
9)当前元素(父元素里面的第一个子元素)与父元素没有设置任何浮动的情况下,设置 margin-top 后 会错误的把 margin-top 加在父元素上
hack1:给父元素添加声明 overflow:hidden;
hack1:: 给父元素的子元素添加浮动
当两个上下排列的元素,上元素有 margin-bottom 下面元素有 margin-top:他们的中间间距不会叠加而是设置为较大值
10)鼠标指针 bug
描述:cursor 属性的 hand 属性值只有 ie9 以下的浏览器识别,其他浏览器不识别该声明 cursor 属性 pointer 属性值 ie6 以上版本及其他内核浏览器都识别该声明
hack:如统一某元素鼠标指针形状为手型,应添加声明 cursor:pointer;
11)透明属性
兼容其它浏览器写法:opacity:value;(value 取值 0 -1)
ie 浏览器写法:filter:alpha(opacity=value);取值 1 -100(整数)
12)Html 对象获取问题
FireFox:document.getElementById(“idName”);
ie:document.idname 或者 document.getElementById(“idName”).
解决办法:统一使用 document.getElementById(“idName”);
12)event.x 与 event.y 问题
描述: IE 下 event 对象有 x,y 属性, 但是没有 pageX,pageY 属性;
Firefox 下 event 对象有 pageX,pageY 属性, 但是没有 x,y 属性.
解决方法:使用 mX(mX = event.x ? event.x : event.pageX;)来代替 IE 下的 event.x 或者 Firefox 下的 event.pageX.
13)window.location.href 问题
描述:IE 或者 Firefox2.0.x 下,可以使用 window.location 或 window.location.href;
Firefox1.5.x 下, 只能使用 window.location。
解决方法:使用 window.location 来代替 window.location.href。
14)frame 问题
以下面的 frame 为例:
<frame src="xxx.html" id="frameId" name="frameName" />
(1)访问 frame 对象:
IE: 使用 window.frameId 或者 window.frameName 来访问这个 frame 对象, frameId 和 frameName 可以同名。
Firefox: 只能使用 window.frameName 来访问这个 frame 对象.
另外,在 IE 和 Firefox 中都可以使用 window.document.getElementById(“frameId”)来访问这个 frame 对象.
(2)切换 frame 内容:
在 IE 和 Firefox 中都可以使用 window.document.getElementById(“testFrame”).src = “xxx.html” 或 window.frameName.location = “xxx.html” 来切换 frame 的内容.
如果需要将 frame 中的参数传回父窗口(注意不是 opener, 而是 parent frame),可以在 frame 中使用 parent 来访问父窗口。例如:parent.document.form1.filename.value=”Aqing”;
15)模态和非模态窗口问题
说明:IE 下, 可以通过 showModalDialog 和 showModelessDialog 打开模态和非模态窗口;Firefox 下则不能.
解决方法:直接使用 window.open(pageURL,name,parameters)方式打开新窗口。
如果需要将子窗口中的参数传递回父窗口, 可以在子窗口中使用 window.opener 来访问父窗口.
例如:
var parWin = window.opener;
parWin.document.getElementById("Aqing").value = "Aqing";