茗空间

常见兼容性问题

兼容性问题一直都是个头疼的问题,以至于很多接触过前端编程大部分人都会说页面太难调了。这篇文章是对常见兼容性问题的记录,有个问题是肯定不全,因为太多了,只是总结常见的兼容性问题
持续更新中。。。

CSS

1
2
3
4
5
6
7
8
9
10
11
12
// 区分所有主流浏览器的hack:
.element{
color:#000; /*w3c标准*/
[;color:#f00;]; /*Webkit(chrome和safari)*/
color:#666\9; /*IE8*/
*color:#999; /*IE7*/
_color:#333; /*IE6*/
}
:root .element{color:#0f0\9;} /*IE9*/
@media all and (-webkit-min-device-pixel-ratio:10000), not all and (
-webkit-min-device-pixel-ratio:0) { .element{color:#336699;}} /*opera*/
@-moz-document url-prefix(){ .element{color:#f1f1f1;}} /*Firefox*/
  • 怪异模式会出现不可预料的错误,所以在文档最上面使用<!DOCTYPE html>;

  • 浏览器默认的margin和padding不同,使用reset解决,但是不要这样设置:* {margin:0; padding:0 },因为效率;

  • chrome中文界面下默认会将小于12px的文本强制按12px显示,使用-webkit-text-size-adjust:none;已经不能解决问题了,应该这样设置

1
2
3
4
5
.fontsize2 {
/*-webkit-text-size-adjust: none;*/
font-size: 9px;
-webkit-transform: scale(0.75);/*12x0.75=9*/
}
1
2
3
4
/* 在IE下div.child是居中现实的,但是在firefox和chrome下是left */
.container {
text-align: center;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div class="container">
<div class="child">
child's content
</div>
</div>
```
解决方案如下:
```css
/* 方法一:*/
.container {
text-align: center;
text-align: -webkit-center;
text-align: -moz-center;
}
/* 方法二:*/
.container {
text-align: center;
}
.container .child {
margin: auto;
}
  • 不能自动展开包含框:触发Layout来解决height:1%触法haslayout有一定风险,所以应使用height:0;或height:1px,但是overflow:hidden与height不能同时设置(同时设置height的值就回对元素的真实高度产生影响),此时应使用zoom:1或者display:inline-block来触法haslayout

  • 列表布局问题

1
2
3
4
5
6
7
8
9
10
<style>
ul {
width: 60%;
}
</style>
<ul>
<li>li1</li>
<li>li2</li>
<li>li3</li>
</ul>

定义列表宽度为60%,那么ul元素就拥有了layout特性,如果在ie浏览,会发现列表的项目符号消失了。
解决如下:

1
2
3
4
ul {
width: 60%;
padding-left: 1em;
}
  • 在IE6及以下版本浏览器中,当列表项元素li中包含有块状现实的超链接元素时,列表元素之间的空格将不会被忽略,而且会额外增加一行;
1
2
3
4
5
6
7
8
9
.a2,.a3 {
display: block;
}
<ol>
<li class="l1"><a href="#" class="a1">a1</a></li>
<li class="l2"><a href="#" class="a2">a2</a></li>
<li class="l3"><a href="#" class="a3">a3</a></li>
<li class="l4"><a href="#" class="a4">a4</a></li>
</ol>

在l3和l4下面都会多出一个空行;
解决如下:

1
2
3
4
.a2,.a3 {
display: block;
zoom: 1;
}
  • 定位布局问题

由于相对定位不能触法Layout特性,所以在使用定位时会出现莫名其妙的错误,如定位对象丢失、定位元素错位等,所以建议相对定位元素声名zoom:1

  • IE6当在浮动元素之间增加HTML注释时下方会出现多余字符;

  • IE6 躲猫猫BUG的解决方案

  • IE浏览器出现背景与内容分离时,考虑触发Layout特性来解决

JS

更多关于dom操作的兼容性请参考《js高级程序设计(第三版)》第10章

  • safari9.0.3中,Date(‘2015-10-10’)返回Invalid Date,因为它不认识’-‘,可以换成Date(‘2015/10/10’);

  • 以前有篇文章:跨浏览器的EventUtil&&StyleUtil

  • ie可以使用常规属性方法获取自定义属性(elment.customProp),也可以使用getAttribute(“customProp”)获取,FireFox只能使用getAttribute();

  • ie的event对象有x,y(看这里)属性,没有pageX,pageY;Fireforx下有pageX,pageY,没有x,y;

  • IE8前event没有pageX,pageY,解决如下

1
2
3
4
5
6
7
8
9
10
11
event = event || window.event;
var pageX = event.pageX;
pageY = event.pageY;
if (pageX === undefined) {
// document.body(混杂模式),document.documentElement(标准模式)
pageX = event.clientX + (document.body.scrollLeft || document.documentElement.scrollLeft);
}
if (pageY === undefined) {
pageY = event.clientY + (document.body.scrollTop || document.documentElement.scrollTop);
}
  • cloneNode()方法在IE下会复制事件处理程序(非IE下不会),所以在复制之前最好先移除事件处理程序;

  • 在IE中可以给createElement()传入完整的元素标签,也可以包含属性:

1
2
3
4
5
6
7
8
var div = document.createElement("<div id=\"myNewDiv\" class=\"box\"></div>");
/*
*这种方法有助于避开IE7及更早版本中动态创建元素的某些问题:
*1.不能设置动态创建的iframe元素的name特性;
*2.不能通过表单的reset方法重设动态创建的input元素;
*3.动态创建的type特性为reset的button元素重设不了表单
*4.动态创建的一批name相同的单选按钮彼此毫无关系。
*/
  • attributes属性,在IE7及更早版本会返回HTML元素中所有可能的特性,包括没有指定的特性。可以通过attribute的specified属性过滤,所有未设置过的特性该属性都是false,而其它浏览器不会为这类特性生成特性节点。

  • 下面代码在IE解析下ul会有3个字节点(3个li),而在其他浏览器会有7个元素(3个li和4个li元素之间的文本节点):

1
2
3
4
5
<ul id="myList">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
  • IE不允许访问script和style的子节点,所以动态创建script和style应这样处理:
1
2
3
4
5
6
7
8
9
10
11
// Script
function loadScriptString(code) {
var script = document.createElement("script");
script.type = "text/javascript";
try {
script.appendChild(document.createTextNode(code));
} catch(e) {
script.text = code;
}
document.body.appendChild(script);
}
1
2
3
4
5
6
7
8
9
10
11
12
// Style
function loadStyleString(code) {
var style = document.createElement('style');
style.type = "text/css";
try {
style.appendChild(document.createTextNode(code));
} catch(e) {
style.styleSheet.cssText = code;
}
var head = document.getElementsByTagName("head")[0];
head.appendChild(style);
}
  • style,getComputedStyle,currentStyle,defaultView的区别
    获取元素CSS值之getComputedStyle方法熟悉
    有几点需要注意:
    1、虽然currentStyle与getComputedStyle都是获取计算后的属性,但是键名还是有不少差异,比如“浮动”对应的键名可能是
    cssFloat与styleFloat,获取值的时候应该这样
1
window.getComputedStyle(element, null).getPropertyValue("float");// 属性名不需要驼峰式

2、但是ie9之前又不支持getPropertyValue,在老的IE浏览器(包括最新的),getAttribute方法提供了与getPropertyValue方法类似的功能

1
style.getAttribute("backgroundColor"); //属性名需要是驼峰式
  • IE下是支持firstChild,lastChild,nextSibling,previousSibling,
    但是在FF下,由于它会把标签之间的空格当成文本节点,所以为了准确地找到相应的元素,应该使用
    :firstElementChild,lastElementChild,nextElementSibling,
    previousElementSibling

参考

  1. Block formatting context:介绍块级格式化上下文;
  2. 前端精选文摘:BFC 神奇背后的原理:介绍了什么是BFC,及BFC的应用;
  3. 前端知识点:介绍了各种需要了解的点;
  4. Definition of “containingblock”:包含快的定义
  5. 前端精选文摘:那些年我们一起清除过的浮动:内容包括如何触发BFC和hasLayout
  6. IE6中的常见BUG与相应的解决办法
  7. 获取元素CSS值之getComputedStyle方法熟悉
  8. 兼容的firstChild,lastChild,nextSibling,previousSibling写法(转)